Index: /trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 7533)
+++ /trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 7534)
@@ -48,5 +48,6 @@
 
 /**
- * Join Areas (i.e. closed ways and multipolygons)
+ * Join Areas (i.e. closed ways and multipolygons).
+ * @since 2575
  */
 public class JoinAreasAction extends JosmAction {
@@ -57,7 +58,6 @@
 
     /**
-     * This helper class describes join ares action result.
+     * This helper class describes join areas action result.
      * @author viesturs
-     *
      */
     public static class JoinAreasResult {
@@ -394,10 +394,18 @@
 
     /**
-     * Gets called whenever the shortcut is pressed or the menu entry is selected
-     * Checks whether the selected objects are suitable to join and joins them if so
+     * Gets called whenever the shortcut is pressed or the menu entry is selected.
+     * Checks whether the selected objects are suitable to join and joins them if so.
      */
     @Override
     public void actionPerformed(ActionEvent e) {
-        LinkedList<Way> ways = new LinkedList<>(Main.main.getCurrentDataSet().getSelectedWays());
+        join(Main.main.getCurrentDataSet().getSelectedWays());
+    }
+
+    /**
+     * Joins the given ways.
+     * @param ways Ways to join
+     * @since 7534
+     */
+    public void join(Collection<Way> ways) {
         addedRelations.clear();
 
@@ -471,6 +479,8 @@
                 }
                 DataSet ds = Main.main.getCurrentDataSet();
-                ds.setSelected(allWays);
-                Main.map.mapView.repaint();
+                if (ds != null) {
+                    ds.setSelected(allWays);
+                    Main.map.mapView.repaint();
+                }
             } else {
                 new Notification(
@@ -479,6 +489,5 @@
                         .show();
             }
-        }
-        catch (UserCancelException exception) {
+        } catch (UserCancelException exception) {
             //revert changes
             //FIXME: this is dirty hack
@@ -915,5 +924,5 @@
     /**
      * This is a method splits way into smaller parts, using the prepared nodes list as split points.
-     * Uses  SplitWayAction.splitWay for the heavy lifting.
+     * Uses {@link SplitWayAction#splitWay} for the heavy lifting.
      * @return list of split ways (or original ways if no splitting is done).
      */
@@ -924,5 +933,5 @@
 
         if (chunks.size() > 1) {
-            SplitWayResult split = SplitWayAction.splitWay(Main.main.getEditLayer(), way, chunks, Collections.<OsmPrimitive>emptyList());
+            SplitWayResult split = SplitWayAction.splitWay(getEditLayer(), way, chunks, Collections.<OsmPrimitive>emptyList());
 
             //execute the command, we need the results
@@ -1254,5 +1263,5 @@
      * @return list of polygons, or null if too complex relation encountered.
      */
-    private List<Multipolygon> collectMultipolygons(List<Way> selectedWays) {
+    private List<Multipolygon> collectMultipolygons(Collection<Way> selectedWays) {
 
         List<Multipolygon> result = new ArrayList<>();
@@ -1380,5 +1389,5 @@
 
     /**
-     * Removes a given OsmPrimitive from all relations
+     * Removes a given OsmPrimitive from all relations.
      * @param osm Element to remove from all relations
      * @return List of relations with roles the primitives was part of
Index: /trunk/src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 7533)
+++ /trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 7534)
@@ -84,5 +84,5 @@
             putValue("toolbar", toolbarId);
         }
-        if (registerInToolbar) {
+        if (registerInToolbar && Main.toolbar != null) {
             Main.toolbar.register(this);
         }
@@ -205,5 +205,5 @@
      */
     protected static OsmDataLayer getEditLayer() {
-        return Main.main.getEditLayer();
+        return Main.main != null ? Main.main.getEditLayer() : null;
     }
 
@@ -214,5 +214,5 @@
      */
     protected static DataSet getCurrentDataSet() {
-        return Main.main.getCurrentDataSet();
+        return Main.main != null ? Main.main.getCurrentDataSet() : null;
     }
 
Index: /trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 7533)
+++ /trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 7534)
@@ -358,7 +358,6 @@
             newWays.add(wayToAdd);
             wayToAdd.setNodes(chunkIt.next());
-            commandList.add(new AddCommand(layer,wayToAdd));
+            commandList.add(new AddCommand(layer, wayToAdd));
             newSelection.add(wayToAdd);
-
         }
         boolean warnmerole = false;
@@ -381,21 +380,19 @@
                 if (rm.isWay() && rm.getMember() == way) {
                     boolean insert = true;
-                    if ("restriction".equals(type))
-                    {
+                    if ("restriction".equals(type)) {
                         /* this code assumes the restriction is correct. No real error checking done */
                         String role = rm.getRole();
-                        if("from".equals(role) || "to".equals(role))
-                        {
+                        if("from".equals(role) || "to".equals(role)) {
                             OsmPrimitive via = null;
                             for (RelationMember rmv : r.getMembers()) {
-                                if("via".equals(rmv.getRole())){
+                                if ("via".equals(rmv.getRole())){
                                     via = rmv.getMember();
                                 }
                             }
                             List<Node> nodes = new ArrayList<>();
-                            if(via != null) {
-                                if(via instanceof Node) {
+                            if (via != null) {
+                                if (via instanceof Node) {
                                     nodes.add((Node)via);
-                                } else if(via instanceof Way) {
+                                } else if (via instanceof Way) {
                                     nodes.add(((Way)via).lastNode());
                                     nodes.add(((Way)via).firstNode());
@@ -403,11 +400,10 @@
                             }
                             Way res = null;
-                            for(Node n : nodes) {
+                            for (Node n : nodes) {
                                 if(changedWay.isFirstLastNode(n)) {
                                     res = way;
                                 }
                             }
-                            if(res == null)
-                            {
+                            if (res == null) {
                                 for (Way wayToAdd : newWays) {
                                     for(Node n : nodes) {
@@ -417,6 +413,5 @@
                                     }
                                 }
-                                if(res != null)
-                                {
+                                if (res != null) {
                                     if (c == null) {
                                         c = new Relation(r);
@@ -429,10 +424,8 @@
                                 insert = false;
                             }
-                        }
-                        else if(!"via".equals(role)) {
+                        } else if(!"via".equals(role)) {
                             warnme = true;
                         }
-                    }
-                    else if (!("route".equals(type)) && !("multipolygon".equals(type))) {
+                    } else if (!("route".equals(type)) && !("multipolygon".equals(type))) {
                         warnme = true;
                     }
@@ -441,6 +434,5 @@
                     }
 
-                    if(insert)
-                    {
+                    if (insert) {
                         if (rm.hasRole() && !nowarnroles.contains(rm.getRole())) {
                             warnmerole = true;
@@ -484,9 +476,10 @@
                     }
                 }
-                i_c++; i_r++;
+                i_c++;
+                i_r++;
             }
 
             if (c != null) {
-                commandList.add(new ChangeCommand(layer,r, c));
+                commandList.add(new ChangeCommand(layer, r, c));
             }
         }
Index: /trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 7533)
+++ /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 7534)
@@ -923,7 +923,10 @@
 
     protected void refreshTitle() {
-        boolean dirty = editLayer != null && (editLayer.requiresSaveToFile() || (editLayer.requiresUploadToServer() && !editLayer.isUploadDiscouraged()));
-        ((JFrame) Main.parent).setTitle((dirty ? "* " : "") + tr("Java OpenStreetMap Editor"));
-        ((JFrame) Main.parent).getRootPane().putClientProperty("Window.documentModified", dirty);
+        if (Main.parent != null) {
+            boolean dirty = editLayer != null &&
+                    (editLayer.requiresSaveToFile() || (editLayer.requiresUploadToServer() && !editLayer.isUploadDiscouraged()));
+            ((JFrame) Main.parent).setTitle((dirty ? "* " : "") + tr("Java OpenStreetMap Editor"));
+            ((JFrame) Main.parent).getRootPane().putClientProperty("Window.documentModified", dirty);
+        }
     }
 
Index: /trunk/test/data/regress/10511/10511_mini.osm
===================================================================
--- /trunk/test/data/regress/10511/10511_mini.osm	(revision 7534)
+++ /trunk/test/data/regress/10511/10511_mini.osm	(revision 7534)
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<osm version='0.6' upload='true' generator='JOSM'>
+  <node id='-68' action='modify' visible='true' lat='55.18135539257' lon='-7.98285399308'>
+    <tag k='ref' v='D' />
+  </node>
+  <node id='-66' action='modify' visible='true' lat='55.1808426071' lon='-7.98215939005'>
+    <tag k='ref' v='B' />
+  </node>
+  <node id='-64' action='modify' visible='true' lat='55.18081456395' lon='-7.98219447101'>
+    <tag k='ref' v='C' />
+  </node>
+  <node id='-62' action='modify' visible='true' lat='55.18078652078' lon='-7.98196293666'>
+    <tag k='ref' v='A' />
+  </node>
+  <node id='-60' action='modify' visible='true' lat='55.18061024901' lon='-7.98460804115'>
+    <tag k='ref' v='E' />
+  </node>
+  <way id='-70' action='modify' visible='true'>
+    <nd ref='-60' />
+    <nd ref='-62' />
+    <nd ref='-66' />
+    <nd ref='-62' />
+    <nd ref='-66' />
+    <nd ref='-64' />
+    <nd ref='-66' />
+    <nd ref='-68' />
+    <nd ref='-60' />
+    <tag k='building' v='yes' />
+  </way>
+</osm>
Index: /trunk/test/unit/org/openstreetmap/josm/actions/JoinAreasActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/actions/JoinAreasActionTest.java	(revision 7534)
+++ /trunk/test/unit/org/openstreetmap/josm/actions/JoinAreasActionTest.java	(revision 7534)
@@ -0,0 +1,49 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.MainApplication;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.io.OsmReader;
+
+/**
+ * Unit tests of {@link JoinAreasAction} class.
+ */
+public class JoinAreasActionTest {
+
+    /**
+     * Setup test.
+     */
+    @BeforeClass
+    public static void setUp() {
+        JOSMFixture.createUnitTestFixture().init();
+        Main.toolbar = new ToolbarPreferences();
+        new MainApplication();
+        Main.main.createMapFrame(null, null);
+    }
+
+    /**
+     * Non-regression test for bug #10511.
+     * @throws IOException if any I/O error occurs
+     * @throws IllegalDataException if OSM parsing fails
+     */
+    @Test
+    public void testTicket10511() throws IOException, IllegalDataException {
+        try (InputStream is = new FileInputStream(TestUtils.getRegressionDataFile(10511, "10511_mini.osm"))) {
+            DataSet ds = OsmReader.parseDataSet(is, null);
+            Main.map.mapView.addLayer(new OsmDataLayer(ds, null, null));
+            new JoinAreasAction().join(ds.getWays());
+        }
+    }
+}
