Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 11397)
@@ -499,5 +499,5 @@
                     }
                 }
-            } else {
+            } else if (bestMovement != null) {
                 if (mode == Mode.extrude || mode == Mode.create_new) {
                     //nothing here
@@ -897,16 +897,20 @@
         // set neighboring segments
         Node prevNode = getPreviousNode(selectedSegment.lowerIndex);
-        EastNorth prevNodeEn = prevNode.getEastNorth();
-        dualAlignSegment1 = new ReferenceSegment(new EastNorth(
-            initialN1en.getX() - prevNodeEn.getX(),
-            initialN1en.getY() - prevNodeEn.getY()
-            ), initialN1en, prevNodeEn, false);
+        if (prevNode != null) {
+            EastNorth prevNodeEn = prevNode.getEastNorth();
+            dualAlignSegment1 = new ReferenceSegment(new EastNorth(
+                initialN1en.getX() - prevNodeEn.getX(),
+                initialN1en.getY() - prevNodeEn.getY()
+                ), initialN1en, prevNodeEn, false);
+        }
 
         Node nextNode = getNextNode(selectedSegment.lowerIndex + 1);
-        EastNorth nextNodeEn = nextNode.getEastNorth();
-        dualAlignSegment2 = new ReferenceSegment(new EastNorth(
-            initialN2en.getX() - nextNodeEn.getX(),
-            initialN2en.getY() - nextNodeEn.getY()
-            ), initialN2en, nextNodeEn, false);
+        if (nextNode != null) {
+            EastNorth nextNodeEn = nextNode.getEastNorth();
+            dualAlignSegment2 = new ReferenceSegment(new EastNorth(
+                initialN2en.getX() - nextNodeEn.getX(),
+                initialN2en.getY() - nextNodeEn.getY()
+                ), initialN2en, nextNodeEn, false);
+        }
     }
 
Index: trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 11397)
@@ -213,5 +213,10 @@
      */
     protected String getServerKey() {
-        return getUrlNoException().getHost();
+        try {
+            return getUrl().getHost();
+        } catch (IOException e) {
+            Main.trace(e);
+            return null;
+        }
     }
 
@@ -255,5 +260,10 @@
         Set<ICachedLoaderListener> listeners;
         synchronized (inProgress) {
-            listeners = inProgress.remove(getUrlNoException().toString());
+            try {
+                listeners = inProgress.remove(getUrl().toString());
+            } catch (IOException e) {
+                listeners = null;
+                Main.trace(e);
+            }
         }
         if (listeners == null) {
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 11397)
@@ -15,4 +15,5 @@
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -499,4 +500,5 @@
      */
     public void addPrimitive(OsmPrimitive primitive) {
+        Objects.requireNonNull(primitive, "primitive");
         beginUpdate();
         try {
Index: trunk/src/org/openstreetmap/josm/data/osm/Node.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/data/osm/Node.java	(revision 11397)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.data.osm;
 
+import java.awt.geom.Area;
 import java.util.Collection;
 import java.util.Objects;
@@ -420,6 +421,11 @@
     @Override
     public boolean isOutsideDownloadArea() {
-        return !isNewOrUndeleted() && getDataSet() != null && getDataSet().getDataSourceArea() != null
-                && getCoor() != null && !getCoor().isIn(getDataSet().getDataSourceArea());
+        if (isNewOrUndeleted() || getDataSet() == null)
+            return false;
+        Area area = getDataSet().getDataSourceArea();
+        if (area == null)
+            return false;
+        LatLon coor = getCoor();
+        return coor != null && !coor.isIn(area);
     }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 11397)
@@ -116,5 +116,8 @@
                 if (idx == -1)
                     return this;
-                return getChild(idx).findBucket(bbox);
+                QBLevel<T> child = getChild(idx);
+                if (child == null)
+                    return this;
+                return child.findBucket(bbox);
             }
         }
@@ -140,7 +143,5 @@
         /*
          * There is a race between this and qb.nextContentNode().
-         * If nextContentNode() runs into this bucket, it may
-         * attempt to null out 'children' because it thinks this
-         * is a dead end.
+         * If nextContentNode() runs into this bucket, it may attempt to null out 'children' because it thinks this is a dead end.
          */
         void doSplit() {
@@ -153,5 +154,7 @@
                     doAddContent(o);
                 } else {
-                    getChild(idx).doAdd(o);
+                    QBLevel<T> child = getChild(idx);
+                    if (child != null)
+                        child.doAdd(o);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/data/osm/WaySegment.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/WaySegment.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/data/osm/WaySegment.java	(revision 11397)
@@ -94,5 +94,5 @@
     @Override
     public int compareTo(WaySegment o) {
-        return equals(o) ? 0 : toWay().compareTo(o.toWay());
+        return o == null ? -1 : (equals(o) ? 0 : toWay().compareTo(o.toWay()));
     }
 
Index: trunk/src/org/openstreetmap/josm/data/validation/routines/DomainValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/routines/DomainValidator.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/data/validation/routines/DomainValidator.java	(revision 11397)
@@ -221,4 +221,5 @@
      */
     public boolean isValidInfrastructureTld(String iTld) {
+        if (iTld == null) return false;
         final String key = chompLeadingDot(unicodeToASCII(iTld).toLowerCase(Locale.ENGLISH));
         return arrayContains(INFRASTRUCTURE_TLDS, key);
@@ -233,4 +234,5 @@
      */
     public boolean isValidGenericTld(String gTld) {
+        if (gTld == null) return false;
         final String key = chompLeadingDot(unicodeToASCII(gTld).toLowerCase(Locale.ENGLISH));
         return (arrayContains(GENERIC_TLDS, key) || arrayContains(genericTLDsPlus, key))
@@ -246,4 +248,5 @@
      */
     public boolean isValidCountryCodeTld(String ccTld) {
+        if (ccTld == null) return false;
         final String key = chompLeadingDot(unicodeToASCII(ccTld).toLowerCase(Locale.ENGLISH));
         return (arrayContains(COUNTRY_CODE_TLDS, key) || arrayContains(countryCodeTLDsPlus, key))
@@ -259,4 +262,5 @@
      */
     public boolean isValidLocalTld(String lTld) {
+        if (lTld == null) return false;
         final String key = chompLeadingDot(unicodeToASCII(lTld).toLowerCase(Locale.ENGLISH));
         return arrayContains(LOCAL_TLDS, key);
Index: trunk/src/org/openstreetmap/josm/gui/help/HelpUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/help/HelpUtil.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/gui/help/HelpUtil.java	(revision 11397)
@@ -69,5 +69,6 @@
     public static String getHelpTopicEditUrl(String absoluteHelpTopic) {
         String topicUrl = getHelpTopicUrl(absoluteHelpTopic);
-        topicUrl = topicUrl.replaceAll("#[^#]*$", ""); // remove optional fragment
+        if (topicUrl != null)
+            topicUrl = topicUrl.replaceAll("#[^#]*$", ""); // remove optional fragment
         return topicUrl + "?action=edit";
     }
@@ -84,5 +85,8 @@
         if (topic == null)
             return null;
-        String pattern = "/[A-Z][a-z]{1,2}(_[A-Z]{2})?:" + getHelpTopicPrefix(LocaleType.ENGLISH).replaceAll("^\\/+", "");
+        String topicPrefix = getHelpTopicPrefix(LocaleType.ENGLISH);
+        if (topicPrefix != null)
+            topicPrefix = topicPrefix.replaceAll("^\\/+", "");
+        String pattern = "/[A-Z][a-z]{1,2}(_[A-Z]{2})?:" + topicPrefix;
         if (url.matches(pattern)) {
             return topic.substring(pattern.length());
@@ -100,12 +104,12 @@
     public static String extractAbsoluteHelpTopic(String url) {
         if (url == null || !url.startsWith(getWikiBaseHelpUrl())) return null;
-        url = url.substring(getWikiBaseHelpUrl().length());
+        String topic = url.substring(getWikiBaseHelpUrl().length());
         String prefix = getHelpTopicPrefix(LocaleType.ENGLISH);
-        if (url.startsWith(prefix))
-            return url;
+        if (prefix == null || topic.startsWith(prefix))
+            return topic;
 
         String pattern = "/[A-Z][a-z]{1,2}(_[A-Z]{2})?:" + prefix.replaceAll("^\\/+", "");
-        if (url.matches(pattern))
-            return url;
+        if (topic.matches(pattern))
+            return topic;
 
         return null;
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 11397)
@@ -425,5 +425,8 @@
             switch (column) {
             case VersionTableColumnModel.COL_VERSION:
-                return Long.toString(getPrimitive(row).getVersion());
+                HistoryOsmPrimitive p1 = getPrimitive(row);
+                if (p1 != null)
+                    return Long.toString(p1.getVersion());
+                return null;
             case VersionTableColumnModel.COL_REFERENCE:
                 return isReferencePointInTime(row);
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 11397)
@@ -504,7 +504,9 @@
                         if (e.hasThumbnail()) {
                             Dimension d = scaledDimension(e.getThumbnail());
-                            Rectangle target = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
-                            if (clip.intersects(target)) {
-                                tempG.drawImage(e.getThumbnail(), target.x, target.y, target.width, target.height, null);
+                            if (d != null) {
+                                Rectangle target = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
+                                if (clip.intersects(target)) {
+                                    tempG.drawImage(e.getThumbnail(), target.x, target.y, target.width, target.height, null);
+                                }
                             }
                         } else { // thumbnail not loaded yet
@@ -540,6 +542,11 @@
                 if (useThumbs && e.hasThumbnail()) {
                     Dimension d = scaledDimension(e.getThumbnail());
-                    imgWidth = d.width;
-                    imgHeight = d.height;
+                    if (d != null) {
+                        imgWidth = d.width;
+                        imgHeight = d.height;
+                    } else {
+                        imgWidth = -1;
+                        imgHeight = -1;
+                    }
                 } else {
                     imgWidth = selectedIcon.getIconWidth();
@@ -756,5 +763,8 @@
                 if (useThumbs && img.hasThumbnail()) {
                     Dimension d = scaledDimension(img.getThumbnail());
-                    r = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
+                    if (d != null)
+                        r = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
+                    else
+                        r = null;
                 } else {
                     r = new Rectangle(p.x - icon.getIconWidth() / 2,
@@ -763,5 +773,5 @@
                                       icon.getIconHeight());
                 }
-                if (r.contains(evt.getPoint())) {
+                if (r != null && r.contains(evt.getPoint())) {
                     return img;
                 }
@@ -861,5 +871,8 @@
                     if (useThumbs && e.hasThumbnail()) {
                         Dimension d = scaledDimension(e.getThumbnail());
-                        r = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
+                        if (d != null)
+                            r = new Rectangle(p.x - d.width / 2, p.y - d.height / 2, d.width, d.height);
+                        else
+                            r = null;
                     } else {
                         r = new Rectangle(p.x - icon.getIconWidth() / 2,
@@ -868,5 +881,5 @@
                                 icon.getIconHeight());
                     }
-                    if (r.contains(ev.getPoint())) {
+                    if (r != null && r.contains(ev.getPoint())) {
                         clearOtherCurrentPhotos();
                         currentPhoto = i;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 11397)
@@ -402,24 +402,26 @@
         // create a task for downloading plugins if the user has activated, yet not downloaded, new plugins
         final PluginPreference preference = getPluginPreference();
-        final Set<PluginInformation> toDownload = preference.getPluginsScheduledForUpdateOrDownload();
-        final PluginDownloadTask task;
-        if (toDownload != null && !toDownload.isEmpty()) {
-            task = new PluginDownloadTask(this, toDownload, tr("Download plugins"));
-        } else {
-            task = null;
-        }
-
-        // this is the task which will run *after* the plugins are downloaded
-        final Runnable continuation = new PluginDownloadAfterTask(preference, task, toDownload);
-
-        if (task != null) {
-            // if we have to launch a plugin download task we do it asynchronously, followed
-            // by the remaining "save preferences" activites run on the Swing EDT.
-            Main.worker.submit(task);
-            Main.worker.submit(() -> SwingUtilities.invokeLater(continuation));
-        } else {
-            // no need for asynchronous activities. Simply run the remaining "save preference"
-            // activities on this thread (we are already on the Swing EDT
-            continuation.run();
+        if (preference != null) {
+            final Set<PluginInformation> toDownload = preference.getPluginsScheduledForUpdateOrDownload();
+            final PluginDownloadTask task;
+            if (toDownload != null && !toDownload.isEmpty()) {
+                task = new PluginDownloadTask(this, toDownload, tr("Download plugins"));
+            } else {
+                task = null;
+            }
+
+            // this is the task which will run *after* the plugins are downloaded
+            final Runnable continuation = new PluginDownloadAfterTask(preference, task, toDownload);
+
+            if (task != null) {
+                // if we have to launch a plugin download task we do it asynchronously, followed
+                // by the remaining "save preferences" activites run on the Swing EDT.
+                Main.worker.submit(task);
+                Main.worker.submit(() -> SwingUtilities.invokeLater(continuation));
+            } else {
+                // no need for asynchronous activities. Simply run the remaining "save preference"
+                // activities on this thread (we are already on the Swing EDT
+                continuation.run();
+            }
         }
     }
Index: trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 11397)
@@ -94,5 +94,6 @@
                 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
                 GpxData result = downloadRawGps(new Bounds(lat1, lon1, lat2, 180.0), progressMonitor);
-                result.mergeFrom(downloadRawGps(new Bounds(lat1, -180.0, lat2, lon2), progressMonitor));
+                if (result != null)
+                    result.mergeFrom(downloadRawGps(new Bounds(lat1, -180.0, lat2, lon2), progressMonitor));
                 return result;
             } else {
Index: trunk/src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 11397)
@@ -399,8 +399,9 @@
                 } else if (currentState != State.LINK) {
                     Map<String, Object> attr = getAttr();
-                    if (!attr.containsKey(META_LINKS)) {
+                    if (attr != null && !attr.containsKey(META_LINKS)) {
                         attr.put(META_LINKS, new LinkedList<GpxLink>());
                     }
-                    ((Collection<GpxLink>) attr.get(META_LINKS)).add(currentLink);
+                    if (attr != null)
+                        ((Collection<GpxLink>) attr.get(META_LINKS)).add(currentLink);
                 }
                 break;
Index: trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 11397)
@@ -891,9 +891,11 @@
             Map<String, PluginInformation> infos = loadLocallyAvailablePluginInformation(monitor.createSubTaskMonitor(1, false));
             List<PluginInformation> ret = new LinkedList<>();
-            for (Iterator<String> it = plugins.iterator(); it.hasNext();) {
-                String plugin = it.next();
-                if (infos.containsKey(plugin)) {
-                    ret.add(infos.get(plugin));
-                    it.remove();
+            if (infos != null) {
+                for (Iterator<String> it = plugins.iterator(); it.hasNext();) {
+                    String plugin = it.next();
+                    if (infos.containsKey(plugin)) {
+                        ret.add(infos.get(plugin));
+                        it.remove();
+                    }
                 }
             }
Index: trunk/src/org/openstreetmap/josm/tools/AudioPlayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/AudioPlayer.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/tools/AudioPlayer.java	(revision 11397)
@@ -124,5 +124,7 @@
      */
     public static void play(URL url) throws Exception {
-        AudioPlayer.getInstance().command.play(url, 0.0, 1.0);
+        AudioPlayer instance = AudioPlayer.getInstance();
+        if (instance != null)
+            instance.command.play(url, 0.0, 1.0);
     }
 
@@ -134,5 +136,7 @@
      */
     public static void play(URL url, double seconds) throws Exception {
-        AudioPlayer.getInstance().command.play(url, seconds, 1.0);
+        AudioPlayer instance = AudioPlayer.getInstance();
+        if (instance != null)
+            instance.command.play(url, seconds, 1.0);
     }
 
@@ -145,5 +149,7 @@
      */
     public static void play(URL url, double seconds, double speed) throws Exception {
-        AudioPlayer.getInstance().command.play(url, seconds, speed);
+        AudioPlayer instance = AudioPlayer.getInstance();
+        if (instance != null)
+            instance.command.play(url, seconds, speed);
     }
 
@@ -153,5 +159,7 @@
      */
     public static void pause() throws Exception {
-        AudioPlayer.getInstance().command.pause();
+        AudioPlayer instance = AudioPlayer.getInstance();
+        if (instance != null)
+            instance.command.pause();
     }
 
@@ -161,5 +169,6 @@
      */
     public static URL url() {
-        return AudioPlayer.getInstance().playingUrl;
+        AudioPlayer instance = AudioPlayer.getInstance();
+        return instance == null ? null : instance.playingUrl;
     }
 
@@ -169,5 +178,6 @@
      */
     public static boolean paused() {
-        return AudioPlayer.getInstance().state == State.PAUSED;
+        AudioPlayer instance = AudioPlayer.getInstance();
+        return instance == null ? false : (instance.state == State.PAUSED);
     }
 
@@ -177,5 +187,6 @@
      */
     public static boolean playing() {
-        return AudioPlayer.getInstance().state == State.PLAYING;
+        AudioPlayer instance = AudioPlayer.getInstance();
+        return instance == null ? false : (instance.state == State.PLAYING);
     }
 
@@ -185,5 +196,6 @@
      */
     public static double position() {
-        return AudioPlayer.getInstance().position;
+        AudioPlayer instance = AudioPlayer.getInstance();
+        return instance == null ? -1 : instance.position;
     }
 
@@ -193,5 +205,6 @@
      */
     public static double speed() {
-        return AudioPlayer.getInstance().speed;
+        AudioPlayer instance = AudioPlayer.getInstance();
+        return instance == null ? -1 : instance.speed;
     }
 
Index: trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 11397)
@@ -510,5 +510,6 @@
         return tr("<html>Failed to upload data to or download data from<br>" + "''{0}''<br>"
                 + "due to a problem with transferring data.<br>"
-                + "Details (untranslated): {1}</html>", e.getUrl(),
+                + "Details (untranslated): {1}</html>",
+                e != null ? e.getUrl() : "null",
                 ioe != null ? ioe.getMessage() : "null");
     }
Index: trunk/src/org/openstreetmap/josm/tools/Logging.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Logging.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/tools/Logging.java	(revision 11397)
@@ -261,6 +261,8 @@
         StringWriter sb = new StringWriter();
         sb.append(getErrorLog(message, t));
-        sb.append('\n');
-        t.printStackTrace(new PrintWriter(sb));
+        if (t != null) {
+            sb.append('\n');
+            t.printStackTrace(new PrintWriter(sb));
+        }
         return sb.toString();
     }
Index: trunk/src/org/openstreetmap/josm/tools/Shortcut.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Shortcut.java	(revision 11396)
+++ trunk/src/org/openstreetmap/josm/tools/Shortcut.java	(revision 11397)
@@ -205,6 +205,6 @@
 
     public boolean isEvent(KeyEvent e) {
-        return getKeyStroke() != null && getKeyStroke().equals(
-        KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers()));
+        KeyStroke ks = getKeyStroke();
+        return ks != null && ks.equals(KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers()));
     }
 
