Index: /applications/editors/josm/plugins/reltoolbox/.checkstyle
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/.checkstyle	(revision 32395)
+++ /applications/editors/josm/plugins/reltoolbox/.checkstyle	(revision 32395)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+  <local-check-config name="JOSM" location="/JOSM/tools/checkstyle/josm_checks.xml" type="project" description="">
+    <additional-data name="protect-config-file" value="false"/>
+  </local-check-config>
+  <fileset name="all" enabled="true" check-config-name="JOSM" local="true">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+  <filter name="DerivedFiles" enabled="true"/>
+  <filter name="FilesFromPackage" enabled="true">
+    <filter-data value="src/com"/>
+    <filter-data value="src/gnu"/>
+    <filter-data value="src/javax"/>
+    <filter-data value="src/oauth"/>
+    <filter-data value="src/org/apache"/>
+    <filter-data value="src/org/glassfish"/>
+    <filter-data value="src/org/jdesktop"/>
+    <filter-data value="src/org/openstreetmap/gui"/>
+    <filter-data value="src/org/openstreetmap/josm/gui/mappaint/mapcss/parsergen"/>
+    <filter-data value="src/org/w3"/>
+    <filter-data value="data"/>
+    <filter-data value="images"/>
+    <filter-data value="styles"/>
+    <filter-data value="resources"/>
+    <filter-data value="scripts"/>
+  </filter>
+</fileset-config>
Index: /applications/editors/josm/plugins/reltoolbox/.project
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/.project	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/.project	(revision 32395)
@@ -16,7 +16,13 @@
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
 	</natures>
 </projectDescription>
Index: /applications/editors/josm/plugins/reltoolbox/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/.settings/org.eclipse.jdt.ui.prefs	(revision 32395)
+++ /applications/editors/josm/plugins/reltoolbox/.settings/org.eclipse.jdt.ui.prefs	(revision 32395)
@@ -0,0 +1,60 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=false
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=true
+sp_cleanup.use_lambda=true
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_type_arguments=false
Index: /applications/editors/josm/plugins/reltoolbox/build.xml
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/build.xml	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/build.xml	(revision 32395)
@@ -4,5 +4,5 @@
     <property name="commit.message" value="RelToolbox: make natural sort for relation and find relation lists"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-    <property name="plugin.main.version" value="7392"/>
+    <property name="plugin.main.version" value="10279"/>
 
     <property name="plugin.author" value="Ilya Zverev"/>
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelation.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelation.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelation.java	(revision 32395)
@@ -1,13 +1,35 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext;
 
-import java.awt.*;
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Stroke;
 import java.awt.geom.GeneralPath;
-import java.util.*;
+import java.util.HashSet;
+import java.util.Set;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
-import org.openstreetmap.josm.data.osm.*;
-import org.openstreetmap.josm.data.osm.event.*;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataSetListener;
+import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
+import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
+import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
+import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
 import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
+import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
@@ -18,12 +40,11 @@
  * @author Zverik
  */
-public class ChosenRelation implements EditLayerChangeListener, MapViewPaintable, DataSetListener {
+public class ChosenRelation implements ActiveLayerChangeListener, MapViewPaintable, DataSetListener {
     protected Relation chosenRelation = null;
     private Set<ChosenRelationListener> chosenRelationListeners = new HashSet<>();
 
-    public void set( Relation rel ) {
-        if( rel == chosenRelation || (rel != null && chosenRelation != null && rel.equals(chosenRelation)) ) {
+    public void set(Relation rel) {
+        if (rel == chosenRelation || (rel != null && chosenRelation != null && rel.equals(chosenRelation)))
             return; // new is the same as old
-        }
         Relation oldRel = chosenRelation;
         chosenRelation = rel;
@@ -33,7 +54,8 @@
     }
 
-    protected void fireRelationChanged( Relation oldRel ) {
-        for( ChosenRelationListener listener : chosenRelationListeners )
+    protected void fireRelationChanged(Relation oldRel) {
+        for (ChosenRelationListener listener : chosenRelationListeners) {
             listener.chosenRelationChanged(oldRel, chosenRelation);
+        }
     }
 
@@ -46,15 +68,15 @@
     }
 
-    public boolean isSame( Object r ) {
-        if( r == null )
+    public boolean isSame(Object r) {
+        if (r == null )
             return chosenRelation == null;
-        else if( !(r instanceof Relation) )
+        else if (!(r instanceof Relation) )
             return false;
         else
             return chosenRelation != null && r.equals(chosenRelation);
     }
-    
-    private final static String[] MULTIPOLYGON_TYPES = new String[] {
-        "multipolygon", "boundary"
+
+    private static final String[] MULTIPOLYGON_TYPES = new String[] {
+            "multipolygon", "boundary"
     };
 
@@ -66,12 +88,12 @@
     }
 
-    public static boolean isMultipolygon( Relation r ) {
-        if( r == null )
+    public static boolean isMultipolygon(Relation r) {
+        if (r == null )
             return false;
         String type = r.get("type");
-        if( type == null )
+        if (type == null )
             return false;
-        for( String t : MULTIPOLYGON_TYPES )
-            if( t.equals(type) )
+        for (String t : MULTIPOLYGON_TYPES )
+            if (t.equals(type) )
                 return true;
         return false;
@@ -90,33 +112,35 @@
     }
 
-    public void addChosenRelationListener( ChosenRelationListener listener ) {
+    public void addChosenRelationListener(ChosenRelationListener listener) {
         chosenRelationListeners.add(listener);
     }
 
-    public void removeChosenRelationListener( ChosenRelationListener listener ) {
+    public void removeChosenRelationListener(ChosenRelationListener listener) {
         chosenRelationListeners.remove(listener);
     }
 
-    public void editLayerChanged( OsmDataLayer oldLayer, OsmDataLayer newLayer ) {
+    @Override
+    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
         // todo: dim chosen relation when changing layer
         // todo: check this WTF!
+        OsmDataLayer newLayer = Main.getLayerManager().getEditLayer();
         clear();
-        if( newLayer != null && oldLayer == null ) {
+        if (newLayer != null && e.getPreviousEditLayer() == null) {
             Main.map.mapView.addTemporaryLayer(this);
-        } else if( newLayer == null ) {
+        } else if (newLayer == null) {
             Main.map.mapView.removeTemporaryLayer(this);
         }
     }
 
-    public void paint( Graphics2D g, MapView mv, Bounds bbox ) {
-        if( chosenRelation == null ) {
+    @Override
+    public void paint(Graphics2D g, MapView mv, Bounds bbox) {
+        if (chosenRelation == null)
             return;
-        }
 
         OsmDataLayer dataLayer = mv.getEditLayer();
         float opacity = dataLayer == null ? 0.0f : !dataLayer.isVisible() ? 0.0f : (float)dataLayer.getOpacity();
-        if( opacity < 0.01 )
+        if (opacity < 0.01 )
             return;
-        
+
         Composite oldComposite = g.getComposite();
         Stroke oldStroke = g.getStroke();
@@ -124,24 +148,25 @@
         g.setColor(Color.yellow);
         g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f * opacity));
-        
+
         drawRelations(g, mv, bbox, chosenRelation);
-        
+
         g.setComposite(oldComposite);
         g.setStroke(oldStroke);
-        
-    }
+
+    }
+
     private void drawRelations(Graphics2D g, MapView mv, Bounds bbox, Relation rel) {
-        for( OsmPrimitive element : rel.getMemberPrimitives() ) {
-            if( element.getType() == OsmPrimitiveType.NODE ) {
+        for (OsmPrimitive element : rel.getMemberPrimitives()) {
+            if (element.getType() == OsmPrimitiveType.NODE) {
                 Node node = (Node)element;
                 Point center = mv.getPoint(node);
                 g.drawOval(center.x - 4, center.y - 4, 9, 9);
-            } else if( element.getType() == OsmPrimitiveType.WAY ) {
+            } else if (element.getType() == OsmPrimitiveType.WAY) {
                 Way way = (Way)element;
-                if( way.getNodesCount() >= 2 ) {
+                if (way.getNodesCount() >= 2) {
                     GeneralPath b = new GeneralPath();
                     Point p = mv.getPoint(way.getNode(0));
                     b.moveTo(p.x, p.y);
-                    for( int i = 1; i < way.getNodesCount(); i++ ) {
+                    for (int i = 1; i < way.getNodesCount(); i++) {
                         p = mv.getPoint(way.getNode(i));
                         b.lineTo(p.x, p.y);
@@ -149,5 +174,5 @@
                     g.draw(b);
                 }
-            } else if( element.getType() == OsmPrimitiveType.RELATION ) {
+            } else if (element.getType() == OsmPrimitiveType.RELATION) {
                 Color oldColor = g.getColor();
                 g.setColor(Color.magenta);
@@ -159,31 +184,45 @@
     }
 
-    public void relationMembersChanged( RelationMembersChangedEvent event ) {
-        if( chosenRelation != null && event.getRelation().equals(chosenRelation) )
+    @Override
+    public void relationMembersChanged(RelationMembersChangedEvent event) {
+        if (chosenRelation != null && event.getRelation().equals(chosenRelation) ) {
             fireRelationChanged(chosenRelation);
-    }
-    
-    public void tagsChanged( TagsChangedEvent event ) {
-        if( chosenRelation != null && event.getPrimitive().equals(chosenRelation) )
+        }
+    }
+
+    @Override
+    public void tagsChanged(TagsChangedEvent event) {
+        if (chosenRelation != null && event.getPrimitive().equals(chosenRelation) ) {
             fireRelationChanged(chosenRelation);
-    }
-
-    public void dataChanged( DataChangedEvent event ) {
-        if( chosenRelation != null )
+        }
+    }
+
+    @Override
+    public void dataChanged(DataChangedEvent event) {
+        if (chosenRelation != null ) {
             fireRelationChanged(chosenRelation);
-    }
-
-    public void primitivesRemoved( PrimitivesRemovedEvent event ) {
-        if( chosenRelation != null && event.getPrimitives().contains(chosenRelation) )
+        }
+    }
+
+    @Override
+    public void primitivesRemoved(PrimitivesRemovedEvent event) {
+        if (chosenRelation != null && event.getPrimitives().contains(chosenRelation) ) {
             clear();
-    }
-
-    public void wayNodesChanged( WayNodesChangedEvent event ) {
-        if( chosenRelation != null )
+        }
+    }
+
+    @Override
+    public void wayNodesChanged(WayNodesChangedEvent event) {
+        if (chosenRelation != null )
+        {
             fireRelationChanged(chosenRelation); // download incomplete primitives doesn't cause dataChanged event
-    }
-
-    public void primitivesAdded( PrimitivesAddedEvent event ) {}
-    public void nodeMoved( NodeMovedEvent event ) {}
-    public void otherDatasetChange( AbstractDatasetChangedEvent event ) {}
+        }
+    }
+
+    @Override
+    public void primitivesAdded(PrimitivesAddedEvent event) {}
+    @Override
+    public void nodeMoved(NodeMovedEvent event) {}
+    @Override
+    public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelationComponent.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelationComponent.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelationComponent.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext;
 
@@ -18,5 +19,5 @@
     public ChosenRelationComponent(ChosenRelation rel) {
         super("");
-/*        setBackground(Color.white);
+        /*        setBackground(Color.white);
         setOpaque(true);
         setBorder(new LineBorder(Color.black, 1, true));*/
@@ -25,45 +26,53 @@
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setText(prepareText(newRelation));
         repaint();
     }
-    
+
     private final static String[] TYPE_KEYS = new String[] {
-        "natural", "landuse", "place", "waterway", "leisure", "amenity", "restriction", "public_transport", "route", "enforcement"
+            "natural", "landuse", "place", "waterway", "leisure", "amenity", "restriction", "public_transport", "route", "enforcement"
     };
 
     private final static String[] NAMING_TAGS = new String[] {
-        "name", "place_name", "ref", "destination", "note"
+            "name", "place_name", "ref", "destination", "note"
     };
 
-    protected String prepareText( Relation rel ) {
-        if( rel == null )
+    protected String prepareText(Relation rel) {
+        if (rel == null )
             return "";
 
         String type = rel.get("type");
-        if( type == null || type.length() == 0 )
+        if (type == null || type.length() == 0 ) {
             type = "-";
+        }
 
         String tag = null;
-        for( int i = 0; i < TYPE_KEYS.length && tag == null; i++ )
-            if( rel.hasKey(TYPE_KEYS[i]))
+        for (int i = 0; i < TYPE_KEYS.length && tag == null; i++ )
+            if (rel.hasKey(TYPE_KEYS[i])) {
                 tag = TYPE_KEYS[i];
-        if( tag != null )
+            }
+        if (tag != null ) {
             tag = tag.substring(0, 2) + "=" + rel.get(tag);
+        }
 
         String name = null;
-        for( int i = 0; i < NAMING_TAGS.length && name == null; i++ )
-            if( rel.hasKey(NAMING_TAGS[i]) )
+        for (int i = 0; i < NAMING_TAGS.length && name == null; i++ )
+            if (rel.hasKey(NAMING_TAGS[i]) ) {
                 name = rel.get(NAMING_TAGS[i]);
+            }
 
         StringBuilder sb = new StringBuilder();
         sb.append(type.substring(0, 1));
-        if( type.equals("boundary") && rel.hasKey("admin_level") )
+        if (type.equals("boundary") && rel.hasKey("admin_level") ) {
             sb.append(rel.get("admin_level"));
-        if( name != null )
+        }
+        if (name != null ) {
             sb.append(" \"").append(name).append('"');
-        if( tag != null )
+        }
+        if (tag != null ) {
             sb.append("; ").append(tag);
+        }
         sb.append(" (").append(rel.getMembersCount()).append(')');
 
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelationListener.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelationListener.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/ChosenRelationListener.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext;
 
@@ -9,4 +10,4 @@
  */
 public interface ChosenRelationListener {
-    void chosenRelationChanged( Relation oldRelation, Relation newRelation );
+    void chosenRelationChanged(Relation oldRelation, Relation newRelation);
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/ExtraNameFormatHook.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/ExtraNameFormatHook.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/ExtraNameFormatHook.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext;
 
@@ -8,37 +9,42 @@
 /**
  * Formatter hook for some tags that Dirk does not want to support.
- * 
+ *
  * @author Zverik
  */
 public class ExtraNameFormatHook implements NameFormatterHook {
 
-    public String checkRelationTypeName( IRelation relation, String defaultName ) {
-    return null;
+    @Override
+    public String checkRelationTypeName(IRelation relation, String defaultName) {
+        return null;
     }
 
-    public String checkFormat( INode node, String defaultName ) {
-    return null;
+    @Override
+    public String checkFormat(INode node, String defaultName) {
+        return null;
     }
 
-    public String checkFormat( IWay way, String defaultName ) {
-    if( way.get("place") != null && way.get("name") == null && way.get("place_name") != null )
-        return way.get("place_name") + " " + defaultName;
-    return null;
+    @Override
+    public String checkFormat(IWay way, String defaultName) {
+        if (way.get("place") != null && way.get("name") == null && way.get("place_name") != null )
+            return way.get("place_name") + " " + defaultName;
+        return null;
     }
 
-    public String checkFormat( IRelation relation, String defaultName ) {
-    String type = relation.get("type");
-    if( type != null ) {
-        String name = relation.get("destination");
-        if( type.equals("destination_sign") && name != null ) {
-        if( relation.get("distance") != null )
-            name += " " + relation.get("distance");
-        if( defaultName.indexOf('"') < 0 )
-            return '"' + name + "\" " + defaultName;
-        else
-            return defaultName.replaceFirst("\".?+\"", '"'+name+'"');
+    @Override
+    public String checkFormat(IRelation relation, String defaultName) {
+        String type = relation.get("type");
+        if (type != null) {
+            String name = relation.get("destination");
+            if (type.equals("destination_sign") && name != null) {
+                if (relation.get("distance") != null ) {
+                    name += " " + relation.get("distance");
+                }
+                if (defaultName.indexOf('"') < 0 )
+                    return '"' + name + "\" " + defaultName;
+                else
+                    return defaultName.replaceFirst("\".?+\"", '"'+name+'"');
+            }
         }
-    }
-    return null;
+        return null;
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextDialog.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextDialog.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextDialog.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext;
 
@@ -103,5 +104,5 @@
 public class RelContextDialog extends ToggleDialog implements EditLayerChangeListener, ChosenRelationListener, SelectionChangedListener {
 
-    public final static String PREF_PREFIX = "reltoolbox";
+    public static final String PREF_PREFIX = "reltoolbox";
 
     private final DefaultTableModel relationsData;
@@ -124,5 +125,5 @@
         chosenRelation = new ChosenRelation();
         chosenRelation.addChosenRelationListener(this);
-        MapView.addEditLayerChangeListener(chosenRelation);
+        Main.getLayerManager().addActiveLayerChangeListener(chosenRelation);
 
         popupMenu = new ChosenRelationPopupMenu(chosenRelation);
@@ -144,9 +145,9 @@
         roleBox.addItemListener(new ItemListener() {
             @Override
-            public void itemStateChanged( ItemEvent e ) {
-                if( e.getStateChange() == ItemEvent.DESELECTED ) return;
+            public void itemStateChanged(ItemEvent e) {
+                if (e.getStateChange() == ItemEvent.DESELECTED ) return;
                 String memberRole = roleBoxModel.getSelectedMembersRole();
                 String selectedRole = roleBoxModel.isAnotherRoleSelected() ? askForRoleName() : roleBoxModel.getSelectedRole();
-                if( memberRole != null && selectedRole != null && !memberRole.equals(selectedRole) ) {
+                if (memberRole != null && selectedRole != null && !memberRole.equals(selectedRole)) {
                     applyRoleToSelection(selectedRole.trim());
                 }
@@ -177,5 +178,5 @@
         roleBox.addPropertyChangeListener("enabled", new PropertyChangeListener() {
             @Override
-            public void propertyChange( PropertyChangeEvent evt ) {
+            public void propertyChange(PropertyChangeEvent evt) {
                 boolean showRoleBox = roleBox.isEnabled();
                 roleBox.setVisible(showRoleBox);
@@ -186,5 +187,5 @@
         sortAndFixAction.addPropertyChangeListener(new PropertyChangeListener() {
             @Override
-            public void propertyChange( PropertyChangeEvent evt ) {
+            public void propertyChange(PropertyChangeEvent evt) {
                 sortAndFixButton.setVisible(sortAndFixAction.isEnabled());
             }
@@ -194,11 +195,12 @@
         downloadChosenRelationAction.addPropertyChangeListener(new PropertyChangeListener() {
             @Override
-            public void propertyChange( PropertyChangeEvent evt ) {
+            public void propertyChange(PropertyChangeEvent evt) {
                 downloadButton.setVisible(downloadChosenRelationAction.isEnabled());
             }
         });
         downloadButton.setVisible(false);
-        if( Main.pref.getBoolean(PREF_PREFIX + ".hidetopline", false) )
+        if (Main.pref.getBoolean(PREF_PREFIX + ".hidetopline", false) ) {
             chosenRelationPanel.setVisible(false);
+        }
 
         // [+][Multi] [X]Adm [X]Tags [X]1
@@ -209,5 +211,5 @@
         final JButton multipolygonButton = new JButton(createMultipolygonAction);
         bottomLine.add(multipolygonButton, GBC.std());
-//        bottomLine.add(sizeButton(new JButton(new MultipolygonSettingsAction()), 16, 0), GBC.std().fill(GBC.VERTICAL));
+        //        bottomLine.add(sizeButton(new JButton(new MultipolygonSettingsAction()), 16, 0), GBC.std().fill(GBC.VERTICAL));
         bottomLine.add(Box.createHorizontalGlue(), GBC.std().fill());
         findRelationAction = new FindRelationAction(chosenRelation);
@@ -217,16 +219,17 @@
         multipolygonButton.addMouseListener(new MouseAdapter() {
             @Override
-            public void mousePressed( MouseEvent e ) {
+            public void mousePressed(MouseEvent e) {
                 checkPopup(e);
             }
 
             @Override
-            public void mouseReleased( MouseEvent e ) {
+            public void mouseReleased(MouseEvent e) {
                 checkPopup(e);
             }
 
-            private void checkPopup( MouseEvent e ) {
-                if( e.isPopupTrigger() )
+            private void checkPopup(MouseEvent e) {
+                if (e.isPopupTrigger() ) {
                     multiPopupMenu.show(e.getComponent(), e.getX(), e.getY());
+                }
             }
         });
@@ -237,15 +240,15 @@
     private static final Color CHOSEN_RELATION_COLOR = new Color(255, 255, 128);
 
-    private void configureRelationsTable( final JTable relationsTable ) {
+    private void configureRelationsTable(final JTable relationsTable) {
         relationsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
         relationsTable.setTableHeader(null);
         relationsTable.addMouseListener(new MouseAdapter() {
             @Override
-            public void mouseClicked( MouseEvent e ) {
+            public void mouseClicked(MouseEvent e) {
                 Point p = e.getPoint();
                 int row = relationsTable.rowAtPoint(p);
-                if( SwingUtilities.isLeftMouseButton(e) && row >= 0 ) {
+                if (SwingUtilities.isLeftMouseButton(e) && row >= 0) {
                     Relation relation = (Relation)relationsData.getValueAt(row, 0);
-                    if( e.getClickCount() > 1 ) {
+                    if (e.getClickCount() > 1) {
                         Main.main.getEditLayer().data.setSelected(relation);
                     }
@@ -254,15 +257,15 @@
 
             @Override
-            public void mousePressed( MouseEvent e ) {
+            public void mousePressed(MouseEvent e) {
                 checkPopup(e);
             }
 
             @Override
-            public void mouseReleased( MouseEvent e ) {
+            public void mouseReleased(MouseEvent e) {
                 checkPopup(e);
             }
 
-            public void checkPopup( MouseEvent e ) {
-                if( e.isPopupTrigger() ) {
+            public void checkPopup(MouseEvent e) {
+                if (e.isPopupTrigger()) {
                     Point p = e.getPoint();
                     int row = relationsTable.rowAtPoint(p);
@@ -280,15 +283,16 @@
         columns.getColumn(0).setCellRenderer(new OsmPrimitivRenderer() {
             @Override
-            protected String getComponentToolTipText( OsmPrimitive value ) {
+            protected String getComponentToolTipText(OsmPrimitive value) {
                 return null;
             }
 
             @Override
-            public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
+            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                 Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-                if( !isSelected && value instanceof Relation && chosenRelation.isSame(value) )
+                if (!isSelected && value instanceof Relation && chosenRelation.isSame(value) ) {
                     c.setBackground(CHOSEN_RELATION_COLOR);
-                else
+                } else {
                     c.setBackground(table.getBackground());
+                }
                 return c;
             }
@@ -297,10 +301,11 @@
         columns.getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
             @Override
-            public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) {
+            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                 Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-                if( !isSelected && chosenRelation.isSame(table.getValueAt(row, 0)) )
+                if (!isSelected && chosenRelation.isSame(table.getValueAt(row, 0)) ) {
                     c.setBackground(CHOSEN_RELATION_COLOR);
-                else
+                } else {
                     c.setBackground(table.getBackground());
+                }
                 return c;
             }
@@ -310,7 +315,7 @@
         relationsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
             @Override
-            public void valueChanged( ListSelectionEvent e ) {
+            public void valueChanged(ListSelectionEvent e) {
                 int selectedRow = relationsTable.getSelectedRow();
-                if( selectedRow >= 0 ) {
+                if (selectedRow >= 0) {
                     chosenRelation.set((Relation)relationsData.getValueAt(selectedRow, 0));
                     relationsTable.clearSelection();
@@ -320,5 +325,5 @@
     }
 
-    private JComponent sizeButton( JComponent b, int width, int height ) {
+    private JComponent sizeButton(JComponent b, int width, int height) {
         Dimension pref = b.getPreferredSize();
         b.setPreferredSize(new Dimension(width <= 0 ? pref.width : width, height <= 0 ? pref.height : height));
@@ -346,9 +351,11 @@
 
     @Override
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
-        if( chosenRelationPanel != null && Main.pref.getBoolean(PREF_PREFIX + ".hidetopline", false) )
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
+        if (chosenRelationPanel != null && Main.pref.getBoolean(PREF_PREFIX + ".hidetopline", false) ) {
             chosenRelationPanel.setVisible(newRelation != null);
-        if( Main.main.getCurrentDataSet() != null )
+        }
+        if (Main.main.getCurrentDataSet() != null ) {
             selectionChanged(Main.main.getCurrentDataSet().getSelected());
+        }
         roleBoxModel.update();
         // ?
@@ -356,6 +363,6 @@
 
     @Override
-    public void selectionChanged( Collection<? extends OsmPrimitive> newSelection ) {
-        if( !isVisible() || relationsData == null )
+    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+        if (!isVisible() || relationsData == null )
             return;
         roleBoxModel.update();
@@ -363,12 +370,12 @@
         relationsData.setRowCount(0);
         sortAndFixAction.chosenRelationChanged(chosenRelation.get(), chosenRelation.get());
-        if( newSelection == null )
+        if (newSelection == null )
             return;
 
         Set<Relation> relations = new TreeSet<>(
                 DefaultNameFormatter.getInstance().getRelationComparator());
-        for( OsmPrimitive element : newSelection ) {
-            for( OsmPrimitive ref : element.getReferrers() ) {
-                if( ref instanceof Relation && !ref.isIncomplete() && !ref.isDeleted() ) {
+        for (OsmPrimitive element : newSelection) {
+            for (OsmPrimitive ref : element.getReferrers()) {
+                if (ref instanceof Relation && !ref.isIncomplete() && !ref.isDeleted()) {
                     relations.add((Relation) ref);
                 }
@@ -376,12 +383,12 @@
         }
 
-        for( Relation rel : relations ) {
+        for (Relation rel : relations) {
             String role = null;
-            for( RelationMember m : rel.getMembers() ) {
-                for( OsmPrimitive element : newSelection ) {
-                    if( m.getMember().equals(element) ) {
-                        if( role == null )
+            for (RelationMember m : rel.getMembers()) {
+                for (OsmPrimitive element : newSelection) {
+                    if (m.getMember().equals(element)) {
+                        if (role == null ) {
                             role = m.getRole();
-                        else if( !role.equals(m.getRole()) ) {
+                        } else if (!role.equals(m.getRole())) {
                             role = tr("<different>");
                             break;
@@ -392,7 +399,8 @@
             relationsData.addRow(new Object[] {rel, role == null ? "" : role});
         }
-        for( OsmPrimitive element : newSelection )
-            if( element instanceof Relation && !chosenRelation.isSame(element) )
+        for (OsmPrimitive element : newSelection )
+            if (element instanceof Relation && !chosenRelation.isSame(element) ) {
                 relationsData.addRow(new Object[] {element, ""});
+            }
     }
 
@@ -406,5 +414,5 @@
 
     @Override
-    public void editLayerChanged( OsmDataLayer oldLayer, OsmDataLayer newLayer ) {
+    public void editLayerChanged(OsmDataLayer oldLayer, OsmDataLayer newLayer) {
         updateSelection();
     }
@@ -428,19 +436,20 @@
         ClassLoader classLoader = RelContextDialog.class.getClassLoader();
         try (
-            InputStream possibleRolesStream = classLoader.getResourceAsStream(POSSIBLE_ROLES_FILE);
-            BufferedReader r = new BufferedReader(new InputStreamReader(possibleRolesStream));
-        ) {
-            while( r.ready() ) {
+                InputStream possibleRolesStream = classLoader.getResourceAsStream(POSSIBLE_ROLES_FILE);
+                BufferedReader r = new BufferedReader(new InputStreamReader(possibleRolesStream));
+                ) {
+            while(r.ready()) {
                 String line = r.readLine();
                 StringTokenizer t = new StringTokenizer(line, " ,;:\"");
-                if( t.hasMoreTokens() ) {
+                if (t.hasMoreTokens()) {
                     String type = t.nextToken();
                     List<String> roles = new ArrayList<>();
-                    while( t.hasMoreTokens() )
+                    while(t.hasMoreTokens() ) {
                         roles.add(t.nextToken());
+                    }
                     result.put(type, roles);
                 }
             }
-        } catch( Exception e ) {
+        } catch(Exception e) {
             Main.error("[RelToolbox] Error reading possible roles file.");
             Main.error(e);
@@ -453,7 +462,8 @@
 
         List<String> items = new ArrayList<>();
-        for( String role : roleBoxModel.getRoles() ) {
-            if( role.length() > 1 )
+        for (String role : roleBoxModel.getRoles()) {
+            if (role.length() > 1 ) {
                 items.add(role);
+            }
         }
         final AutoCompletingComboBox role = new AutoCompletingComboBox();
@@ -477,5 +487,5 @@
         role.getEditor().addActionListener(new ActionListener() {
             @Override
-            public void actionPerformed( ActionEvent e ) {
+            public void actionPerformed(ActionEvent e) {
                 dlg.setVisible(false);
                 optionPane.setValue(JOptionPane.OK_OPTION);
@@ -486,8 +496,7 @@
 
         Object answer = optionPane.getValue();
-        if( answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
-                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION) ) {
+        if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
+                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION))
             return null;
-        }
 
         return role.getEditor().getItem().toString().trim();
@@ -496,23 +505,23 @@
     private class ChosenRelationMouseAdapter extends MouseAdapter {
         @Override
-        public void mouseClicked( MouseEvent e ) {
-            if( e.isControlDown() || !(e.getComponent() instanceof JComboBox ) ) // do not use left click handler on combo box
-            if( SwingUtilities.isLeftMouseButton(e) && chosenRelation.get() != null && Main.main.getEditLayer() != null ) {
-                Main.main.getEditLayer().data.setSelected(chosenRelation.get());
-            }
-        }
-
-        @Override
-        public void mousePressed( MouseEvent e ) {
+        public void mouseClicked(MouseEvent e) {
+            if (e.isControlDown() || !(e.getComponent() instanceof JComboBox ) ) // do not use left click handler on combo box
+                if (SwingUtilities.isLeftMouseButton(e) && chosenRelation.get() != null && Main.main.getEditLayer() != null) {
+                    Main.main.getEditLayer().data.setSelected(chosenRelation.get());
+                }
+        }
+
+        @Override
+        public void mousePressed(MouseEvent e) {
             checkPopup(e);
         }
 
         @Override
-        public void mouseReleased( MouseEvent e ) {
+        public void mouseReleased(MouseEvent e) {
             checkPopup(e);
         }
 
-        private void checkPopup( MouseEvent e ) {
-            if( e.isPopupTrigger() && chosenRelation.get() != null ) {
+        private void checkPopup(MouseEvent e) {
+            if (e.isPopupTrigger() && chosenRelation.get() != null) {
                 popupMenu.show(e.getComponent(), e.getX(), e.getY() - 5);
             }
@@ -521,5 +530,5 @@
 
     private class ChosenRelationPopupMenu extends JPopupMenu {
-        public ChosenRelationPopupMenu( ChosenRelation chosenRelation ) {
+        public ChosenRelationPopupMenu(ChosenRelation chosenRelation) {
             add(new SelectMembersAction(chosenRelation));
             add(new SelectRelationAction(chosenRelation));
@@ -535,20 +544,20 @@
     }
 
-    protected void applyRoleToSelection( String role ) {
-        if( chosenRelation != null && chosenRelation.get() != null && Main.main.getCurrentDataSet() != null && !Main.main.getCurrentDataSet().selectionEmpty() ) {
+    protected void applyRoleToSelection(String role) {
+        if (chosenRelation != null && chosenRelation.get() != null && Main.main.getCurrentDataSet() != null && !Main.main.getCurrentDataSet().selectionEmpty()) {
             Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
             Relation r = chosenRelation.get();
             List<Command> commands = new ArrayList<>();
-            for( int i = 0; i < r.getMembersCount(); i++ ) {
+            for (int i = 0; i < r.getMembersCount(); i++) {
                 RelationMember m = r.getMember(i);
-                if( selected.contains(m.getMember()) ) {
-                    if( !role.equals(m.getRole()) ) {
-//                        r.setMember(i, new RelationMember(role, m.getMember()));
+                if (selected.contains(m.getMember())) {
+                    if (!role.equals(m.getRole())) {
+                        //                        r.setMember(i, new RelationMember(role, m.getMember()));
                         commands.add(new ChangeRelationMemberRoleCommand(r, i, role));
                     }
                 }
             }
-            if( !commands.isEmpty() ) {
-//                Main.main.undoRedo.add(new ChangeCommand(chosenRelation.get(), r));
+            if (!commands.isEmpty()) {
+                //                Main.main.undoRedo.add(new ChangeCommand(chosenRelation.get(), r));
                 Main.main.undoRedo.add(new SequenceCommand(tr("Change relation member roles to {0}", role), commands));
             }
@@ -567,5 +576,5 @@
         }
     }
-/*
+    /*
     private class MultipolygonSettingsAction extends AbstractAction {
         public MultipolygonSettingsAction() {
@@ -575,5 +584,5 @@
         }
 
-        public void actionPerformed( ActionEvent e ) {
+        public void actionPerformed(ActionEvent e) {
             Component c = e.getSource() instanceof Component ? (Component)e.getSource() : Main.parent;
             multiPopupMenu.show(c, 0, 0);
@@ -591,5 +600,5 @@
         }
 
-        protected final JCheckBoxMenuItem addMenuItem( String property, String title ) {
+        protected final JCheckBoxMenuItem addMenuItem(String property, String title) {
             String fullProperty = PREF_PREFIX + ".multipolygon." + property;
             JCheckBoxMenuItem item = new JCheckBoxMenuItem(tr(title));
@@ -602,7 +611,7 @@
 
         @Override
-        public void actionPerformed( ActionEvent e ) {
+        public void actionPerformed(ActionEvent e) {
             String property = e.getActionCommand();
-            if( property != null && property.length() > 0 && e.getSource() instanceof JCheckBoxMenuItem ) {
+            if (property != null && property.length() > 0 && e.getSource() instanceof JCheckBoxMenuItem) {
                 boolean value = ((JCheckBoxMenuItem)e.getSource()).isSelected();
                 Main.pref.put(property, value);
@@ -617,5 +626,5 @@
             super(tr("Change role"), (String)null, tr("Enter role for selected members"),
                     Shortcut.registerShortcut("reltoolbox:changerole", tr("Relation Toolbox: {0}", tr("Enter role for selected members")),
-                    KeyEvent.VK_R, Shortcut.ALT_CTRL), false, "relcontext/enterrole", true);
+                            KeyEvent.VK_R, Shortcut.ALT_CTRL), false, "relcontext/enterrole", true);
             chosenRelation.addChosenRelationListener(this);
             updateEnabledState();
@@ -623,14 +632,15 @@
 
         @Override
-        public void actionPerformed( ActionEvent e ) {
-            if( roleBoxModel.membersRole != null ) {
+        public void actionPerformed(ActionEvent e) {
+            if (roleBoxModel.membersRole != null) {
                 String role = askForRoleName();
-                if( role != null )
+                if (role != null ) {
                     applyRoleToSelection(role);
-            }
-        }
-
-        @Override
-        public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+                }
+            }
+        }
+
+        @Override
+        public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
             setEnabled(newRelation != null);
         }
@@ -645,5 +655,5 @@
         private final String ANOTHER_ROLE = tr("another...");
 
-        public RoleComboBoxModel( JComboBox<String> combobox ) {
+        public RoleComboBoxModel(JComboBox<String> combobox) {
             super();
             this.combobox = combobox;
@@ -653,37 +663,43 @@
         public void update() {
             membersRole = getSelectedMembersRoleIntl();
-            if( membersRole == null ) {
-                if( combobox.isEnabled() )
+            if (membersRole == null) {
+                if (combobox.isEnabled() ) {
                     combobox.setEnabled(false);
+                }
                 return;
             }
-            if( !combobox.isEnabled() )
+            if (!combobox.isEnabled() ) {
                 combobox.setEnabled(true);
+            }
 
             List<String> items = new ArrayList<>();
-            if( chosenRelation != null && chosenRelation.get() != null ) {
-                if( chosenRelation.isMultipolygon() ) {
+            if (chosenRelation != null && chosenRelation.get() != null) {
+                if (chosenRelation.isMultipolygon()) {
                     items.add("outer");
                     items.add("inner");
                 }
-                if( chosenRelation.get().get("type") != null ) {
+                if (chosenRelation.get().get("type") != null) {
                     List<String> values = possibleRoles.get(chosenRelation.get().get("type"));
-                    if( values != null )
+                    if (values != null ) {
                         items.addAll(values);
-                }
-                for( RelationMember m : chosenRelation.get().getMembers() )
-                    if( m.getRole().length() > 0 && !items.contains(m.getRole()) )
+                    }
+                }
+                for (RelationMember m : chosenRelation.get().getMembers() )
+                    if (m.getRole().length() > 0 && !items.contains(m.getRole()) ) {
                         items.add(m.getRole());
+                    }
             }
             items.add(EMPTY_ROLE);
-            if( !items.contains(membersRole) )
+            if (!items.contains(membersRole) ) {
                 items.add(0, membersRole);
+            }
             items.add(ANOTHER_ROLE);
             roles = Collections.unmodifiableList(items);
 
-            if( membersRole != null )
+            if (membersRole != null ) {
                 setSelectedItem(membersRole);
-            else
+            } else {
                 fireContentsChanged(this, -1, -1);
+            }
             combobox.repaint();
         }
@@ -699,11 +715,11 @@
         private String getSelectedMembersRoleIntl() {
             String role = null;
-            if( chosenRelation != null && chosenRelation.get() != null && Main.main.getCurrentDataSet() != null && !Main.main.getCurrentDataSet().selectionEmpty() ) {
+            if (chosenRelation != null && chosenRelation.get() != null && Main.main.getCurrentDataSet() != null && !Main.main.getCurrentDataSet().selectionEmpty()) {
                 Collection<OsmPrimitive> selected = Main.main.getCurrentDataSet().getSelected();
-                for( RelationMember m : chosenRelation.get().getMembers() ) {
-                    if( selected.contains(m.getMember()) ) {
-                        if( role == null )
+                for (RelationMember m : chosenRelation.get().getMembers()) {
+                    if (selected.contains(m.getMember())) {
+                        if (role == null ) {
                             role = m.getRole();
-                        else if( m.getRole() != null && !role.equals(m.getRole()) ) {
+                        } else if (m.getRole() != null && !role.equals(m.getRole())) {
                             role = tr("<different>");
                             break;
@@ -725,16 +741,16 @@
 
         @Override
-        public String getElementAt( int index ) {
+        public String getElementAt(int index) {
             return getRole(index);
         }
 
-        public String getRole( int index ) {
+        public String getRole(int index) {
             return roles.get(index);
         }
 
         @Override
-        public void setSelectedItem( Object anItem ) {
+        public void setSelectedItem(Object anItem) {
             int newIndex = anItem == null ? -1 : roles.indexOf(anItem);
-            if( newIndex != selectedIndex ) {
+            if (newIndex != selectedIndex) {
                 selectedIndex = newIndex;
                 fireContentsChanged(this, -1, -1);
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextPlugin.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextPlugin.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/RelContextPlugin.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext;
 
@@ -9,13 +10,13 @@
     private RelContextDialog dialog;
 
-    public RelContextPlugin( PluginInformation info ) {
+    public RelContextPlugin(PluginInformation info) {
         super(info);
-    DefaultNameFormatter.registerFormatHook(new ExtraNameFormatHook());
+        DefaultNameFormatter.registerFormatHook(new ExtraNameFormatHook());
     }
 
     @Override
-    public void mapFrameInitialized( MapFrame oldFrame, MapFrame newFrame ) {
-        if( oldFrame == null && newFrame != null ) {
-//            if (dialog!=null) dialog.destroy();
+    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+        if (oldFrame == null && newFrame != null) {
+            //            if (dialog!=null) dialog.destroy();
             dialog = new RelContextDialog();
             newFrame.addToggleDialog(dialog);
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/StaticChosenRelation.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/StaticChosenRelation.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/StaticChosenRelation.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext;
 
@@ -10,5 +11,5 @@
 public class StaticChosenRelation extends ChosenRelation {
 
-    public StaticChosenRelation( Relation rel ) {
+    public StaticChosenRelation(Relation rel) {
         chosenRelation = rel;
         analyse();
@@ -16,6 +17,6 @@
 
     @Override
-    public void set( Relation rel ) {
-//        throw new UnsupportedOperationException("Changing static relation is not supported.");
+    public void set(Relation rel) {
+        //        throw new UnsupportedOperationException("Changing static relation is not supported.");
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/AddRemoveMemberAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/AddRemoveMemberAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/AddRemoveMemberAction.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
@@ -36,8 +37,8 @@
     private SortAndFixAction sortAndFix;
 
-    public AddRemoveMemberAction( ChosenRelation rel, SortAndFixAction sortAndFix ) {
+    public AddRemoveMemberAction(ChosenRelation rel, SortAndFixAction sortAndFix) {
         super(null, "relcontext/addremove", tr("Add/remove members from the chosen relation"),
                 Shortcut.registerShortcut("reltoolbox:addremove", tr("Relation Toolbox: {0}", tr("Add/remove members from the chosen relation")),
-                KeyEvent.VK_EQUALS, Shortcut.DIRECT), false);
+                        KeyEvent.VK_EQUALS, Shortcut.DIRECT), false);
         this.rel = rel;
         this.sortAndFix = sortAndFix;
@@ -46,6 +47,7 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
-        if( rel.get() == null )
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (rel.get() == null )
             return;
 
@@ -63,19 +65,22 @@
 
         // 2. add all new members
-        for( OsmPrimitive p : toAdd ) {
+        for (OsmPrimitive p : toAdd) {
             int pos = -1; //p instanceof Way ? findAdjacentMember(p, r) : -1;
-            if( pos < 0 )
+            if (pos < 0 ) {
                 r.addMember(new RelationMember("", p));
-            else
+            } else {
                 r.addMember(pos, new RelationMember("", p));
+            }
         }
 
         // 3. check for roles again (temporary)
         Command roleFix = !isBroken && sortAndFix.needsFixing(r) ? sortAndFix.fixRelation(r) : null;
-        if( roleFix != null )
+        if (roleFix != null ) {
             roleFix.executeCommand();
+        }
 
-        if( !r.getMemberPrimitives().equals(rel.get().getMemberPrimitives()) )
+        if (!r.getMemberPrimitives().equals(rel.get().getMemberPrimitives()) ) {
             Main.main.undoRedo.add(new ChangeCommand(rel.get(), r));
+        }
     }
 
@@ -84,15 +89,15 @@
      * @see org.openstreetmap.josm.gui.dialogs.relation.MemberTableModel#determineDirection
      */
-    protected int findAdjacentMember( Way w, Relation r ) {
+    protected int findAdjacentMember(Way w, Relation r) {
         Node firstNode = w.firstNode();
         Node lastNode = w.lastNode();
 
-        if( firstNode != null && !firstNode.equals(lastNode) ) {
-            for( int i = 0; i < r.getMembersCount(); i++ ) {
-                if( r.getMember(i).getType().equals(OsmPrimitiveType.WAY) ) {
+        if (firstNode != null && !firstNode.equals(lastNode)) {
+            for (int i = 0; i < r.getMembersCount(); i++) {
+                if (r.getMember(i).getType().equals(OsmPrimitiveType.WAY)) {
                     Way rw = (Way)r.getMember(i).getMember();
                     Node firstNodeR = rw.firstNode();
                     Node lastNodeR = rw.lastNode();
-                    if( firstNode.equals(firstNodeR) || firstNode.equals(lastNodeR) || lastNode.equals(firstNodeR) || lastNode.equals(lastNodeR) )
+                    if (firstNode.equals(firstNodeR) || firstNode.equals(lastNodeR) || lastNode.equals(firstNodeR) || lastNode.equals(lastNodeR) )
                         return i + 1;
                 }
@@ -102,5 +107,6 @@
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         updateEnabledState();
     }
@@ -112,11 +118,11 @@
 
     @Override
-    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
         updateIcon();
-        if( rel == null || rel.get() == null || selection == null || selection.isEmpty() ) {
+        if (rel == null || rel.get() == null || selection == null || selection.isEmpty()) {
             setEnabled(false);
             return;
         }
-        if( selection.size() == 1 && selection.contains(rel.get()) ) {
+        if (selection.size() == 1 && selection.contains(rel.get())) {
             setEnabled(false);
             return;
@@ -128,21 +134,22 @@
         // todo: change icon based on selection
         final int state; // 0=unknown, 1=add, 2=remove, 3=both
-        if( getCurrentDataSet() == null || getCurrentDataSet().getSelected() == null
-                || getCurrentDataSet().getSelected().isEmpty() || rel == null || rel.get() == null )
+        if (getCurrentDataSet() == null || getCurrentDataSet().getSelected() == null
+                || getCurrentDataSet().getSelected().isEmpty() || rel == null || rel.get() == null ) {
             state = 0;
-        else {
+        } else {
             Collection<OsmPrimitive> toAdd = new ArrayList<>(getCurrentDataSet().getSelected());
             toAdd.remove(rel.get());
             int selectedSize = toAdd.size();
-            if( selectedSize == 0 )
+            if (selectedSize == 0 ) {
                 state = 0;
-            else {
+            } else {
                 toAdd.removeAll(rel.get().getMemberPrimitives());
-                if( toAdd.isEmpty() )
+                if (toAdd.isEmpty() ) {
                     state = 2;
-                else if( toAdd.size() < selectedSize )
+                } else if (toAdd.size() < selectedSize ) {
                     state = 3;
-                else
+                } else {
                     state = 1;
+                }
             }
         }
@@ -150,8 +157,8 @@
             @Override
             public void run() {
-//        String name = state == 0 ? "?" : state == 1 ? "+" : state == 2 ? "-" : "±";
-//        putValue(Action.NAME, name);
+                //        String name = state == 0 ? "?" : state == 1 ? "+" : state == 2 ? "-" : "±";
+                //        putValue(Action.NAME, name);
                 if (state == 0) {
-//            putValue(NAME, "?");
+                    //            putValue(NAME, "?");
                     putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", "addremove"));
                 } else {
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ClearChosenRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ClearChosenRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ClearChosenRelationAction.java	(revision 32395)
@@ -1,10 +1,15 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
+import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
+
 import javax.swing.AbstractAction;
 import javax.swing.Action;
-import static org.openstreetmap.josm.tools.I18n.tr;
+
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -13,7 +18,7 @@
     private ChosenRelation rel;
 
-    public ClearChosenRelationAction( ChosenRelation rel ) {
+    public ClearChosenRelationAction(ChosenRelation rel) {
         super();
-//        putValue(Action.NAME, "X");
+        //        putValue(Action.NAME, "X");
         putValue(Action.SMALL_ICON, ImageProvider.get("relcontext", "clear"));
         putValue(Action.SHORT_DESCRIPTION, tr("Clear the chosen relation"));
@@ -23,9 +28,11 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         rel.clear();
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/CreateMultipolygonAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/CreateMultipolygonAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/CreateMultipolygonAction.java	(revision 32395)
@@ -1,18 +1,46 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.Dialog.ModalityType;
 import java.awt.GridBagLayout;
-import static org.openstreetmap.josm.tools.I18n.tr;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
-import java.util.*;
-import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.swing.Box;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.command.*;
-import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.ChangeCommand;
+import org.openstreetmap.josm.command.ChangePropertyCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.osm.MultipolygonBuilder;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.Shortcut;
+
 import relcontext.ChosenRelation;
 
@@ -27,128 +55,140 @@
     protected ChosenRelation chRel;
 
-    public CreateMultipolygonAction( ChosenRelation chRel ) {
-    super("Multi", "data/multipolygon", tr("Create a multipolygon from selected objects"),
-        Shortcut.registerShortcut("reltoolbox:multipolygon", tr("Relation Toolbox: {0}", tr("Create multipolygon")),
-        KeyEvent.VK_A, Shortcut.ALT_CTRL), false);
-    this.chRel = chRel;
-    updateEnabledState();
+    public CreateMultipolygonAction(ChosenRelation chRel) {
+        super("Multi", "data/multipolygon", tr("Create a multipolygon from selected objects"),
+                Shortcut.registerShortcut("reltoolbox:multipolygon", tr("Relation Toolbox: {0}", tr("Create multipolygon")),
+                        KeyEvent.VK_A, Shortcut.ALT_CTRL), false);
+        this.chRel = chRel;
+        updateEnabledState();
     }
 
     public CreateMultipolygonAction() {
-    this(null);
-    }
-
-    public static boolean getDefaultPropertyValue( String property ) {
-    if( property.equals("boundary") )
-        return false;
-    else if( property.equals("boundaryways") )
-        return true;
-    else if( property.equals("tags") )
-        return true;
-    else if( property.equals("alltags") )
-        return false;
-    else if( property.equals("single") )
-        return true;
-    else if( property.equals("allowsplit") )
-        return false;
-    throw new IllegalArgumentException(property);
-    }
-
-    private boolean getPref( String property ) {
-    return Main.pref.getBoolean(PREF_MULTIPOLY + property, getDefaultPropertyValue(property));
-    }
-
-    public void actionPerformed( ActionEvent e ) {
-    boolean isBoundary = getPref("boundary");
-    Collection<Way> selectedWays = getCurrentDataSet().getSelectedWays();
-    if( !isBoundary && getPref("tags") ) {
-        List<Relation> rels = null;
-        if( getPref("allowsplit") || selectedWays.size() == 1 ) {
-        if( SplittingMultipolygons.canProcess(selectedWays) )
-            rels = SplittingMultipolygons.process(getCurrentDataSet().getSelectedWays());
+        this(null);
+    }
+
+    public static boolean getDefaultPropertyValue(String property) {
+        if (property.equals("boundary") )
+            return false;
+        else if (property.equals("boundaryways") )
+            return true;
+        else if (property.equals("tags") )
+            return true;
+        else if (property.equals("alltags") )
+            return false;
+        else if (property.equals("single") )
+            return true;
+        else if (property.equals("allowsplit") )
+            return false;
+        throw new IllegalArgumentException(property);
+    }
+
+    private boolean getPref(String property) {
+        return Main.pref.getBoolean(PREF_MULTIPOLY + property, getDefaultPropertyValue(property));
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        boolean isBoundary = getPref("boundary");
+        Collection<Way> selectedWays = getCurrentDataSet().getSelectedWays();
+        if (!isBoundary && getPref("tags")) {
+            List<Relation> rels = null;
+            if (getPref("allowsplit") || selectedWays.size() == 1) {
+                if (SplittingMultipolygons.canProcess(selectedWays) ) {
+                    rels = SplittingMultipolygons.process(getCurrentDataSet().getSelectedWays());
+                }
+            } else {
+                if (TheRing.areAllOfThoseRings(selectedWays)) {
+                    List<Command> commands = new ArrayList<>();
+                    rels = TheRing.makeManySimpleMultipolygons(getCurrentDataSet().getSelectedWays(), commands);
+                    if (!commands.isEmpty() ) {
+                        Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygons from rings"), commands));
+                    }
+                }
+            }
+            if (rels != null && !rels.isEmpty()) {
+                if (chRel != null ) {
+                    chRel.set(rels.size() == 1 ? rels.get(0) : null);
+                }
+                if (rels.size() == 1 ) {
+                    getCurrentDataSet().setSelected(rels);
+                } else {
+                    getCurrentDataSet().clearSelection();
+                }
+                return;
+            }
+        }
+
+        // for now, just copying standard action
+        MultipolygonBuilder mpc = new MultipolygonBuilder();
+        String error = mpc.makeFromWays(getCurrentDataSet().getSelectedWays());
+        if (error != null) {
+            JOptionPane.showMessageDialog(Main.parent, error);
+            return;
+        }
+        Relation rel = new Relation();
+        if (isBoundary) {
+            rel.put("type", "boundary");
+            rel.put("boundary", "administrative");
         } else {
-        if( TheRing.areAllOfThoseRings(selectedWays) ) {
-            List<Command> commands = new ArrayList<>();
-            rels = TheRing.makeManySimpleMultipolygons(getCurrentDataSet().getSelectedWays(), commands);
-            if( !commands.isEmpty() )
-            Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygons from rings"), commands));
-        }
-        }
-        if( rels != null && !rels.isEmpty() ) {
-        if( chRel != null )
-            chRel.set(rels.size() == 1 ? rels.get(0) : null);
-        if( rels.size() == 1 )
-            getCurrentDataSet().setSelected(rels);
-        else
-            getCurrentDataSet().clearSelection();
-        return;
-        }
-    }
-
-    // for now, just copying standard action
-    MultipolygonBuilder mpc = new MultipolygonBuilder();
-    String error = mpc.makeFromWays(getCurrentDataSet().getSelectedWays());
-    if( error != null ) {
-        JOptionPane.showMessageDialog(Main.parent, error);
-        return;
-    }
-    Relation rel = new Relation();
-    if( isBoundary ) {
-        rel.put("type", "boundary");
-        rel.put("boundary", "administrative");
-    } else
-        rel.put("type", "multipolygon");
-    for( MultipolygonBuilder.JoinedPolygon poly : mpc.outerWays )
-        for( Way w : poly.ways )
-        rel.addMember(new RelationMember("outer", w));
-    for( MultipolygonBuilder.JoinedPolygon poly : mpc.innerWays )
-        for( Way w : poly.ways )
-        rel.addMember(new RelationMember("inner", w));
-    List<Command> list = removeTagsFromInnerWays(rel);
-    if( !list.isEmpty() && isBoundary ) {
-        Main.main.undoRedo.add(new SequenceCommand(tr("Move tags from ways to relation"), list));
-        list = new ArrayList<>();
-    }
-    if( isBoundary ) {
-        if( !askForAdminLevelAndName(rel) )
-        return;
-        addBoundaryMembers(rel);
-        if( getPref("boundaryways") )
-        list.addAll(fixWayTagsForBoundary(rel));
-    }
-    list.add(new AddCommand(rel));
-    Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), list));
-
-    if( chRel != null )
-        chRel.set(rel);
-
-    getCurrentDataSet().setSelected(rel);
+            rel.put("type", "multipolygon");
+        }
+        for (MultipolygonBuilder.JoinedPolygon poly : mpc.outerWays ) {
+            for (Way w : poly.ways ) {
+                rel.addMember(new RelationMember("outer", w));
+            }
+        }
+        for (MultipolygonBuilder.JoinedPolygon poly : mpc.innerWays ) {
+            for (Way w : poly.ways ) {
+                rel.addMember(new RelationMember("inner", w));
+            }
+        }
+        List<Command> list = removeTagsFromInnerWays(rel);
+        if (!list.isEmpty() && isBoundary) {
+            Main.main.undoRedo.add(new SequenceCommand(tr("Move tags from ways to relation"), list));
+            list = new ArrayList<>();
+        }
+        if (isBoundary) {
+            if (!askForAdminLevelAndName(rel) )
+                return;
+            addBoundaryMembers(rel);
+            if (getPref("boundaryways") ) {
+                list.addAll(fixWayTagsForBoundary(rel));
+            }
+        }
+        list.add(new AddCommand(rel));
+        Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), list));
+
+        if (chRel != null ) {
+            chRel.set(rel);
+        }
+
+        getCurrentDataSet().setSelected(rel);
     }
 
     @Override
     protected void updateEnabledState() {
-    if( getCurrentDataSet() == null ) {
-        setEnabled(false);
-    } else {
-        updateEnabledState(getCurrentDataSet().getSelected());
-    }
+        if (getCurrentDataSet() == null) {
+            setEnabled(false);
+        } else {
+            updateEnabledState(getCurrentDataSet().getSelected());
+        }
     }
 
     @Override
-    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
-    boolean isEnabled = true;
-    if( selection == null || selection.isEmpty() )
-        isEnabled = false;
-    else {
-        if( !getPref("boundary") ) {
-        for( OsmPrimitive p : selection ) {
-            if( !(p instanceof Way) ) {
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
+        boolean isEnabled = true;
+        if (selection == null || selection.isEmpty() ) {
             isEnabled = false;
-            break;
-            }
-        }
-        }
-    }
-    setEnabled(isEnabled);
+        } else {
+            if (!getPref("boundary")) {
+                for (OsmPrimitive p : selection) {
+                    if (!(p instanceof Way)) {
+                        isEnabled = false;
+                        break;
+                    }
+                }
+            }
+        }
+        setEnabled(isEnabled);
     }
 
@@ -156,21 +196,23 @@
      * Add selected nodes and relations with corresponding roles.
      */
-    private void addBoundaryMembers( Relation rel ) {
-    for( OsmPrimitive p : getCurrentDataSet().getSelected() ) {
-        String role = null;
-        if( p.getType().equals(OsmPrimitiveType.RELATION) ) {
-        role = "subarea";
-        } else if( p.getType().equals(OsmPrimitiveType.NODE) ) {
-        Node n = (Node)p;
-        if( !n.isIncomplete() ) {
-            if( n.hasKey("place") )
-            role = "admin_centre";
-            else
-            role = "label";
-        }
-        }
-        if( role != null )
-        rel.addMember(new RelationMember(role, p));
-    }
+    private void addBoundaryMembers(Relation rel) {
+        for (OsmPrimitive p : getCurrentDataSet().getSelected()) {
+            String role = null;
+            if (p.getType().equals(OsmPrimitiveType.RELATION)) {
+                role = "subarea";
+            } else if (p.getType().equals(OsmPrimitiveType.NODE)) {
+                Node n = (Node)p;
+                if (!n.isIncomplete()) {
+                    if (n.hasKey("place") ) {
+                        role = "admin_centre";
+                    } else {
+                        role = "label";
+                    }
+                }
+            }
+            if (role != null ) {
+                rel.addMember(new RelationMember(role, p));
+            }
+        }
     }
 
@@ -178,51 +220,57 @@
      * For all untagged ways in relation, add tags boundary and admin_level.
      */
-    private List<Command> fixWayTagsForBoundary( Relation rel ) {
-    List<Command> commands = new ArrayList<>();
-    if( !rel.hasKey("boundary") || !rel.hasKey("admin_level") )
+    private List<Command> fixWayTagsForBoundary(Relation rel) {
+        List<Command> commands = new ArrayList<>();
+        if (!rel.hasKey("boundary") || !rel.hasKey("admin_level") )
+            return commands;
+        String adminLevelStr = rel.get("admin_level");
+        int adminLevel = 0;
+        try {
+            adminLevel = Integer.parseInt(adminLevelStr);
+        } catch(NumberFormatException e) {
+            return commands;
+        }
+        Set<OsmPrimitive> waysBoundary = new HashSet<>();
+        Set<OsmPrimitive> waysAdminLevel = new HashSet<>();
+        for (OsmPrimitive p : rel.getMemberPrimitives()) {
+            if (p instanceof Way) {
+                int count = 0;
+                if (p.hasKey("boundary") && p.get("boundary").equals("administrative") ) {
+                    count++;
+                }
+                if (p.hasKey("admin_level") ) {
+                    count++;
+                }
+                if (p.keySet().size() - count == 0) {
+                    if (!p.hasKey("boundary") ) {
+                        waysBoundary.add(p);
+                    }
+                    if (!p.hasKey("admin_level")) {
+                        waysAdminLevel.add(p);
+                    } else {
+                        try {
+                            int oldAdminLevel = Integer.parseInt(p.get("admin_level"));
+                            if (oldAdminLevel > adminLevel ) {
+                                waysAdminLevel.add(p);
+                            }
+                        } catch(NumberFormatException e) {
+                            waysAdminLevel.add(p); // some garbage, replace it
+                        }
+                    }
+                }
+            }
+        }
+        if (!waysBoundary.isEmpty() ) {
+            commands.add(new ChangePropertyCommand(waysBoundary, "boundary", "administrative"));
+        }
+        if (!waysAdminLevel.isEmpty() ) {
+            commands.add(new ChangePropertyCommand(waysAdminLevel, "admin_level", adminLevelStr));
+        }
         return commands;
-    String adminLevelStr = rel.get("admin_level");
-    int adminLevel = 0;
-    try {
-        adminLevel = Integer.parseInt(adminLevelStr);
-    } catch( NumberFormatException e ) {
-        return commands;
-    }
-    Set<OsmPrimitive> waysBoundary = new HashSet<>();
-    Set<OsmPrimitive> waysAdminLevel = new HashSet<>();
-    for( OsmPrimitive p : rel.getMemberPrimitives() ) {
-        if( p instanceof Way ) {
-        int count = 0;
-        if( p.hasKey("boundary") && p.get("boundary").equals("administrative") )
-            count++;
-        if( p.hasKey("admin_level") )
-            count++;
-        if( p.keySet().size() - count == 0 ) {
-            if( !p.hasKey("boundary") )
-            waysBoundary.add(p);
-            if( !p.hasKey("admin_level") ) {
-            waysAdminLevel.add(p);
-            } else {
-            try {
-                int oldAdminLevel = Integer.parseInt(p.get("admin_level"));
-                if( oldAdminLevel > adminLevel )
-                waysAdminLevel.add(p);
-            } catch( NumberFormatException e ) {
-                waysAdminLevel.add(p); // some garbage, replace it
-            }
-            }
-        }
-        }
-    }
-    if( !waysBoundary.isEmpty() )
-        commands.add(new ChangePropertyCommand(waysBoundary, "boundary", "administrative"));
-    if( !waysAdminLevel.isEmpty() )
-        commands.add(new ChangePropertyCommand(waysAdminLevel, "admin_level", adminLevelStr));
-    return commands;
     }
     static public final List<String> DEFAULT_LINEAR_TAGS = Arrays.asList(new String[] {"barrier", "source"});
     private static final Set<String> REMOVE_FROM_BOUNDARY_TAGS = new TreeSet<>(Arrays.asList(new String[] {
-        "boundary", "boundary_type", "type", "admin_level"
-        }));
+            "boundary", "boundary_type", "type", "admin_level"
+    }));
 
     /**
@@ -231,113 +279,123 @@
      * Todo: rewrite it.
      */
-    private List<Command> removeTagsFromInnerWays( Relation relation ) {
-    Map<String, String> values = new HashMap<>();
-
-    if( relation.hasKeys() ) {
-        for( String key : relation.keySet() ) {
-        values.put(key, relation.get(key));
-        }
-    }
-
-    List<Way> innerWays = new ArrayList<>();
-    List<Way> outerWays = new ArrayList<>();
-
-    Set<String> conflictingKeys = new TreeSet<>();
-
-    for( RelationMember m : relation.getMembers() ) {
-
-        if( m.hasRole() && "inner".equals(m.getRole()) && m.isWay() && m.getWay().hasKeys() ) {
-        innerWays.add(m.getWay());
-        }
-
-        if( m.hasRole() && "outer".equals(m.getRole()) && m.isWay() && m.getWay().hasKeys() ) {
-        Way way = m.getWay();
-        outerWays.add(way);
-        for( String key : way.keySet() ) {
-            if( !values.containsKey(key) ) { //relation values take precedence
-            values.put(key, way.get(key));
-            } else if( !relation.hasKey(key) && !values.get(key).equals(way.get(key)) ) {
-            conflictingKeys.add(key);
-            }
-        }
-        }
-    }
-
-    // filter out empty key conflicts - we need second iteration
-    boolean isBoundary = getPref("boundary");
-    if( isBoundary || !getPref("alltags") )
-        for( RelationMember m : relation.getMembers() )
-        if( m.hasRole() && m.getRole().equals("outer") && m.isWay() )
-            for( String key : values.keySet() )
-            if( !m.getWay().hasKey(key) && !relation.hasKey(key) )
-                conflictingKeys.add(key);
-
-    for( String key : conflictingKeys )
-        values.remove(key);
-
-    for( String linearTag : Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", DEFAULT_LINEAR_TAGS) )
-        values.remove(linearTag);
-
-    if( values.containsKey("natural") && values.get("natural").equals("coastline") )
-        values.remove("natural");
-
-    String name = values.get("name");
-    if( isBoundary ) {
-        Set<String> keySet = new TreeSet<>(values.keySet());
-        for( String key : keySet )
-        if( !REMOVE_FROM_BOUNDARY_TAGS.contains(key) )
+    private List<Command> removeTagsFromInnerWays(Relation relation) {
+        Map<String, String> values = new HashMap<>();
+
+        if (relation.hasKeys()) {
+            for (String key : relation.keySet()) {
+                values.put(key, relation.get(key));
+            }
+        }
+
+        List<Way> innerWays = new ArrayList<>();
+        List<Way> outerWays = new ArrayList<>();
+
+        Set<String> conflictingKeys = new TreeSet<>();
+
+        for (RelationMember m : relation.getMembers()) {
+
+            if (m.hasRole() && "inner".equals(m.getRole()) && m.isWay() && m.getWay().hasKeys()) {
+                innerWays.add(m.getWay());
+            }
+
+            if (m.hasRole() && "outer".equals(m.getRole()) && m.isWay() && m.getWay().hasKeys()) {
+                Way way = m.getWay();
+                outerWays.add(way);
+                for (String key : way.keySet()) {
+                    if (!values.containsKey(key)) { //relation values take precedence
+                        values.put(key, way.get(key));
+                    } else if (!relation.hasKey(key) && !values.get(key).equals(way.get(key))) {
+                        conflictingKeys.add(key);
+                    }
+                }
+            }
+        }
+
+        // filter out empty key conflicts - we need second iteration
+        boolean isBoundary = getPref("boundary");
+        if (isBoundary || !getPref("alltags") ) {
+            for (RelationMember m : relation.getMembers() )
+                if (m.hasRole() && m.getRole().equals("outer") && m.isWay() ) {
+                    for (String key : values.keySet() )
+                        if (!m.getWay().hasKey(key) && !relation.hasKey(key) ) {
+                            conflictingKeys.add(key);
+                        }
+                }
+        }
+
+        for (String key : conflictingKeys ) {
             values.remove(key);
-    }
-
-    values.put("area", "yes");
-
-    List<Command> commands = new ArrayList<>();
-    boolean moveTags = getPref("tags");
-
-    for( String key : values.keySet() ) {
-        List<OsmPrimitive> affectedWays = new ArrayList<>();
-        String value = values.get(key);
-
-        for( Way way : innerWays ) {
-        if( way.hasKey(key) && (isBoundary || value.equals(way.get(key))) ) {
-            affectedWays.add(way);
-        }
-        }
-
-        if( moveTags ) {
-        // remove duplicated tags from outer ways
-        for( Way way : outerWays ) {
-            if( way.hasKey(key) ) {
-            affectedWays.add(way);
-            }
-        }
-        }
-
-        if( affectedWays.size() > 0 ) {
-        commands.add(new ChangePropertyCommand(affectedWays, key, null));
-        }
-    }
-
-    if( moveTags ) {
-        // add those tag values to the relation
-        if( isBoundary )
-        values.put("name", name);
-        boolean fixed = false;
-        Relation r2 = new Relation(relation);
-        for( String key : values.keySet() ) {
-        if( !r2.hasKey(key) && !key.equals("area")
-            && (!isBoundary || key.equals("admin_level") || key.equals("name")) ) {
-            if( relation.isNew() )
-            relation.put(key, values.get(key));
-            else
-            r2.put(key, values.get(key));
-            fixed = true;
-        }
-        }
-        if( fixed && !relation.isNew() )
-        commands.add(new ChangeCommand(relation, r2));
-    }
-
-    return commands;
+        }
+
+        for (String linearTag : Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", DEFAULT_LINEAR_TAGS) ) {
+            values.remove(linearTag);
+        }
+
+        if (values.containsKey("natural") && values.get("natural").equals("coastline") ) {
+            values.remove("natural");
+        }
+
+        String name = values.get("name");
+        if (isBoundary) {
+            Set<String> keySet = new TreeSet<>(values.keySet());
+            for (String key : keySet )
+                if (!REMOVE_FROM_BOUNDARY_TAGS.contains(key) ) {
+                    values.remove(key);
+                }
+        }
+
+        values.put("area", "yes");
+
+        List<Command> commands = new ArrayList<>();
+        boolean moveTags = getPref("tags");
+
+        for (String key : values.keySet()) {
+            List<OsmPrimitive> affectedWays = new ArrayList<>();
+            String value = values.get(key);
+
+            for (Way way : innerWays) {
+                if (way.hasKey(key) && (isBoundary || value.equals(way.get(key)))) {
+                    affectedWays.add(way);
+                }
+            }
+
+            if (moveTags) {
+                // remove duplicated tags from outer ways
+                for (Way way : outerWays) {
+                    if (way.hasKey(key)) {
+                        affectedWays.add(way);
+                    }
+                }
+            }
+
+            if (affectedWays.size() > 0) {
+                commands.add(new ChangePropertyCommand(affectedWays, key, null));
+            }
+        }
+
+        if (moveTags) {
+            // add those tag values to the relation
+            if (isBoundary ) {
+                values.put("name", name);
+            }
+            boolean fixed = false;
+            Relation r2 = new Relation(relation);
+            for (String key : values.keySet()) {
+                if (!r2.hasKey(key) && !key.equals("area")
+                        && (!isBoundary || key.equals("admin_level") || key.equals("name"))) {
+                    if (relation.isNew() ) {
+                        relation.put(key, values.get(key));
+                    } else {
+                        r2.put(key, values.get(key));
+                    }
+                    fixed = true;
+                }
+            }
+            if (fixed && !relation.isNew() ) {
+                commands.add(new ChangeCommand(relation, r2));
+            }
+        }
+
+        return commands;
     }
 
@@ -347,60 +405,62 @@
      * @return false if user pressed "cancel".
      */
-    private boolean askForAdminLevelAndName( Relation rel ) {
-    String relAL = rel.get("admin_level");
-    String relName = rel.get("name");
-    if( relAL != null && relName != null )
+    private boolean askForAdminLevelAndName(Relation rel) {
+        String relAL = rel.get("admin_level");
+        String relName = rel.get("name");
+        if (relAL != null && relName != null )
+            return true;
+
+        JPanel panel = new JPanel(new GridBagLayout());
+        panel.add(new JLabel(tr("Enter admin level and name for the border relation:")), GBC.eol().insets(0, 0, 0, 5));
+
+        final JTextField admin = new JTextField();
+        admin.setText(relAL != null ? relAL : Main.pref.get(PREF_MULTIPOLY + "lastadmin", ""));
+        panel.add(new JLabel(tr("Admin level")), GBC.std());
+        panel.add(Box.createHorizontalStrut(10), GBC.std());
+        panel.add(admin, GBC.eol().fill(GBC.HORIZONTAL).insets(0, 0, 0, 5));
+
+        final JTextField name = new JTextField();
+        if (relName != null ) {
+            name.setText(relName);
+        }
+        panel.add(new JLabel(tr("Name")), GBC.std());
+        panel.add(Box.createHorizontalStrut(10), GBC.std());
+        panel.add(name, GBC.eol().fill(GBC.HORIZONTAL));
+
+        final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
+            @Override
+            public void selectInitialValue() {
+                admin.requestFocusInWindow();
+                admin.selectAll();
+            }
+        };
+        final JDialog dlg = optionPane.createDialog(Main.parent, tr("Create a new relation"));
+        dlg.setModalityType(ModalityType.DOCUMENT_MODAL);
+
+        name.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                dlg.setVisible(false);
+                optionPane.setValue(JOptionPane.OK_OPTION);
+            }
+        });
+
+        dlg.setVisible(true);
+
+        Object answer = optionPane.getValue();
+        if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
+                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION))
+            return false;
+
+        String admin_level = admin.getText().trim();
+        String new_name = name.getText().trim();
+        if (admin_level.equals("10") || (admin_level.length() == 1 && Character.isDigit(admin_level.charAt(0)))) {
+            rel.put("admin_level", admin_level);
+            Main.pref.put(PREF_MULTIPOLY + "lastadmin", admin_level);
+        }
+        if (new_name.length() > 0 ) {
+            rel.put("name", new_name);
+        }
         return true;
-
-    JPanel panel = new JPanel(new GridBagLayout());
-    panel.add(new JLabel(tr("Enter admin level and name for the border relation:")), GBC.eol().insets(0, 0, 0, 5));
-
-    final JTextField admin = new JTextField();
-    admin.setText(relAL != null ? relAL : Main.pref.get(PREF_MULTIPOLY + "lastadmin", ""));
-    panel.add(new JLabel(tr("Admin level")), GBC.std());
-    panel.add(Box.createHorizontalStrut(10), GBC.std());
-    panel.add(admin, GBC.eol().fill(GBC.HORIZONTAL).insets(0, 0, 0, 5));
-
-    final JTextField name = new JTextField();
-    if( relName != null )
-        name.setText(relName);
-    panel.add(new JLabel(tr("Name")), GBC.std());
-    panel.add(Box.createHorizontalStrut(10), GBC.std());
-    panel.add(name, GBC.eol().fill(GBC.HORIZONTAL));
-
-    final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
-        @Override
-        public void selectInitialValue() {
-        admin.requestFocusInWindow();
-        admin.selectAll();
-        }
-    };
-    final JDialog dlg = optionPane.createDialog(Main.parent, tr("Create a new relation"));
-    dlg.setModalityType(ModalityType.DOCUMENT_MODAL);
-
-    name.addActionListener(new ActionListener() {
-        public void actionPerformed( ActionEvent e ) {
-        dlg.setVisible(false);
-        optionPane.setValue(JOptionPane.OK_OPTION);
-        }
-    });
-
-    dlg.setVisible(true);
-
-    Object answer = optionPane.getValue();
-    if( answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
-        || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION) ) {
-        return false;
-    }
-
-    String admin_level = admin.getText().trim();
-    String new_name = name.getText().trim();
-    if( admin_level.equals("10") || (admin_level.length() == 1 && Character.isDigit(admin_level.charAt(0))) ) {
-        rel.put("admin_level", admin_level);
-        Main.pref.put(PREF_MULTIPOLY + "lastadmin", admin_level);
-    }
-    if( new_name.length() > 0 )
-        rel.put("name", new_name);
-    return true;
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/CreateRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/CreateRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/CreateRelationAction.java	(revision 32395)
@@ -1,14 +1,16 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.Dialog.ModalityType;
 import java.awt.GridBagLayout;
-import java.util.Collection;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import static org.openstreetmap.josm.tools.I18n.tr;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
+
 import javax.swing.Box;
 import javax.swing.JDialog;
@@ -16,7 +18,9 @@
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
@@ -24,4 +28,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.Shortcut;
+
 import relcontext.ChosenRelation;
 
@@ -36,8 +41,8 @@
     protected ChosenRelation chRel;
 
-    public CreateRelationAction( ChosenRelation chRel ) {
+    public CreateRelationAction(ChosenRelation chRel) {
         super(tr("New"), "data/relation", tr("Create a relation from selected objects"),
                 Shortcut.registerShortcut("reltoolbox:create", tr("Relation Toolbox: {0}", tr("Create a new relation")),
-                KeyEvent.VK_N, Shortcut.ALT_CTRL), false);
+                        KeyEvent.VK_N, Shortcut.ALT_CTRL), false);
         this.chRel = chRel;
         updateEnabledState();
@@ -48,18 +53,21 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         String type = askForType();
-        if( type == null )
+        if (type == null )
             return;
 
         Relation rel = new Relation();
-        if( type.length() > 0 )
+        if (type.length() > 0 ) {
             rel.put("type", type);
-        for( OsmPrimitive selected : getCurrentDataSet().getSelected() )
+        }
+        for (OsmPrimitive selected : getCurrentDataSet().getSelected() ) {
             rel.addMember(new RelationMember("", selected));
+        }
 
         Main.main.undoRedo.add(new AddCommand(rel));
 
-        if( chRel != null ) {
+        if (chRel != null) {
             chRel.set(rel);
         }
@@ -68,5 +76,5 @@
     @Override
     protected void updateEnabledState() {
-        if( getCurrentDataSet() == null ) {
+        if (getCurrentDataSet() == null) {
             setEnabled(false);
         } else {
@@ -76,5 +84,5 @@
 
     @Override
-    protected void updateEnabledState( Collection<? extends OsmPrimitive> selection ) {
+    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
         setEnabled(selection != null && !selection.isEmpty());
     }
@@ -82,7 +90,7 @@
     // Thanks to TagInfo for the list
     private static final List<String> RELATION_TYPES = Arrays.asList(new String[] {
-        "multipolygon", "boundary", "route", "site", "restriction", "associatedStreet", "public_transport",
-        "street", "collection", "address", "enforcement", "destination_sign", "route_master", "junction",
-        "waterway", "bridge", "tunnel", "surveillance"
+            "multipolygon", "boundary", "route", "site", "restriction", "associatedStreet", "public_transport",
+            "street", "collection", "address", "enforcement", "destination_sign", "route_master", "junction",
+            "waterway", "bridge", "tunnel", "surveillance"
     });
 
@@ -111,5 +119,6 @@
 
         keys.getEditor().addActionListener(new ActionListener() {
-            public void actionPerformed( ActionEvent e ) {
+            @Override
+            public void actionPerformed(ActionEvent e) {
                 dlg.setVisible(false);
                 optionPane.setValue(JOptionPane.OK_OPTION);
@@ -120,8 +129,7 @@
 
         Object answer = optionPane.getValue();
-        if( answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
-                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION) ) {
+        if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
+                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION))
             return null;
-        }
 
         String result = keys.getEditor().getItem().toString().trim();
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DeleteChosenRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DeleteChosenRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DeleteChosenRelationAction.java	(revision 32395)
@@ -1,8 +1,12 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
 import java.util.Collections;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.Command;
@@ -10,4 +14,5 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -16,5 +21,5 @@
     private ChosenRelation rel;
 
-    public DeleteChosenRelationAction( ChosenRelation rel ) {
+    public DeleteChosenRelationAction(ChosenRelation rel) {
         super(tr("Delete relation"));
         putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
@@ -24,13 +29,16 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Relation r = rel.get();
         rel.clear();
         Command c = DeleteCommand.delete(Main.main.getEditLayer(), Collections.singleton(r), true, true);
-        if( c != null )
+        if (c != null ) {
             Main.main.undoRedo.add(c);
+        }
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DownloadChosenRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DownloadChosenRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DownloadChosenRelationAction.java	(revision 32395)
@@ -1,10 +1,14 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -14,4 +18,5 @@
 import org.openstreetmap.josm.gui.dialogs.relation.DownloadRelationTask;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -19,5 +24,5 @@
 /**
  * Downloads or updates chosen relation members, depending on completeness.
- * 
+ *
  * @author Zverik
  */
@@ -25,7 +30,7 @@
     private ChosenRelation rel;
 
-    public DownloadChosenRelationAction( ChosenRelation rel ) {
+    public DownloadChosenRelationAction(ChosenRelation rel) {
         super();
-//        putValue(NAME, "D");
+        //        putValue(NAME, "D");
         putValue(SMALL_ICON, ImageProvider.get("relcontext", "download"));
         putValue(SHORT_DESCRIPTION, tr("Download incomplete members for the chosen relation"));
@@ -35,21 +40,24 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Relation relation = rel.get();
-        if( relation == null || relation.isNew() ) return;
+        if (relation == null || relation.isNew() ) return;
         int total = relation.getMembersCount();
         int incomplete = relation.getIncompleteMembers().size();
-//        if( incomplete <= 5 || (incomplete <= 10 && incomplete * 3 < total) )
-        if( incomplete <= 10 && incomplete * 3 < total )
+        //        if (incomplete <= 5 || (incomplete <= 10 && incomplete * 3 < total) )
+        if (incomplete <= 10 && incomplete * 3 < total ) {
             downloadIncomplete(relation);
-        else
+        } else {
             downloadMembers(relation);
+        }
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         boolean incomplete = false;
-        if( newRelation != null ) {
-            for( RelationMember m : newRelation.getMembers()) {
-                if( m.getMember().isIncomplete() ) {
+        if (newRelation != null) {
+            for (RelationMember m : newRelation.getMembers()) {
+                if (m.getMember().isIncomplete()) {
                     incomplete = true;
                     break;
@@ -60,15 +68,15 @@
     }
 
-    protected void downloadMembers( Relation rel ) {
-        if( !rel.isNew() ) {
+    protected void downloadMembers(Relation rel) {
+        if (!rel.isNew()) {
             Main.worker.submit(new DownloadRelationTask(Collections.singletonList(rel), Main.main.getEditLayer()));
         }
     }
 
-    protected void downloadIncomplete( Relation rel ) {
-        if( rel.isNew() ) return;
+    protected void downloadIncomplete(Relation rel) {
+        if (rel.isNew() ) return;
         Set<OsmPrimitive> ret = new HashSet<>();
         ret.addAll(rel.getIncompleteMembers());
-        if( ret.isEmpty() ) return;
+        if (ret.isEmpty() ) return;
         Main.worker.submit(new DownloadRelationMemberTask(Collections.singletonList(rel), ret, Main.main.getEditLayer()));
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DownloadParentsAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DownloadParentsAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DownloadParentsAction.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
@@ -25,5 +26,5 @@
 /**
  * Downloads parent relations for this relation and all parent objects for its members.
- * 
+ *
  * @author Zverik
  */
@@ -31,5 +32,5 @@
     private ChosenRelation rel;
 
-    public DownloadParentsAction( ChosenRelation rel ) {
+    public DownloadParentsAction(ChosenRelation rel) {
         super(tr("Download referrers"));
         putValue(SMALL_ICON, ImageProvider.get("download"));
@@ -40,7 +41,8 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Relation relation = rel.get();
-        if( relation == null ) return;
+        if (relation == null ) return;
         List<OsmPrimitive> objects = new ArrayList<>();
         objects.add(relation);
@@ -49,19 +51,20 @@
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null && Main.main.getEditLayer() != null);
     }
 
-    protected void downloadMembers( Relation rel ) {
-        if( !rel.isNew() ) {
+    protected void downloadMembers(Relation rel) {
+        if (!rel.isNew()) {
             Main.worker.submit(new DownloadRelationTask(Collections.singletonList(rel), Main.main.getEditLayer()));
         }
     }
 
-    protected void downloadIncomplete( Relation rel ) {
-        if( rel.isNew() ) return;
+    protected void downloadIncomplete(Relation rel) {
+        if (rel.isNew() ) return;
         Set<OsmPrimitive> ret = new HashSet<>();
         ret.addAll(rel.getIncompleteMembers());
-        if( ret.isEmpty() ) return;
+        if (ret.isEmpty() ) return;
         Main.worker.submit(new DownloadRelationMemberTask(Collections.singletonList(rel), ret, Main.main.getEditLayer()));
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DuplicateChosenRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DuplicateChosenRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/DuplicateChosenRelationAction.java	(revision 32395)
@@ -1,11 +1,16 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.AddCommand;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -14,5 +19,5 @@
     private ChosenRelation rel;
 
-    public DuplicateChosenRelationAction( ChosenRelation rel ) {
+    public DuplicateChosenRelationAction(ChosenRelation rel) {
         super(tr("Duplicate relation"));
         putValue(SMALL_ICON, ImageProvider.get("duplicate"));
@@ -23,14 +28,17 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Relation r = rel.get();
         Relation copy = new Relation(r, true);
         Main.main.undoRedo.add(new AddCommand(copy));
         rel.set(copy);
-        if( Main.main.getCurrentDataSet() != null )
+        if (Main.main.getCurrentDataSet() != null ) {
             Main.main.getCurrentDataSet().setSelected(copy);
+        }
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/EditChosenRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/EditChosenRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/EditChosenRelationAction.java	(revision 32395)
@@ -1,11 +1,16 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -13,5 +18,5 @@
 /**
  * Opens an editor for chosen relation.
- * 
+ *
  * @author Zverik
  */
@@ -19,7 +24,7 @@
     private ChosenRelation rel;
 
-    public EditChosenRelationAction( ChosenRelation rel ) {
+    public EditChosenRelationAction(ChosenRelation rel) {
         super();
-//        putValue(NAME, "E");
+        //        putValue(NAME, "E");
         putValue(SMALL_ICON, ImageProvider.get("dialogs/mappaint", "pencil"));
         putValue(SHORT_DESCRIPTION, tr("Open relation editor for the chosen relation"));
@@ -29,11 +34,13 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Relation relation = rel.get();
-        if( relation == null ) return;
+        if (relation == null ) return;
         RelationEditor.getEditor(Main.main.getEditLayer(), relation, null).setVisible(true);
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/FindRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/FindRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/FindRelationAction.java	(revision 32395)
@@ -1,12 +1,32 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.BorderLayout;
 import java.awt.Dialog.ModalityType;
 import java.awt.Dimension;
-import java.awt.event.*;
-import static org.openstreetmap.josm.tools.I18n.tr;
-import java.util.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 import java.util.ArrayList;
-import javax.swing.*;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.AbstractListModel;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JDialog;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
@@ -15,4 +35,5 @@
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
 import org.openstreetmap.josm.tools.Shortcut;
+
 import relcontext.ChosenRelation;
 
@@ -25,12 +46,13 @@
     protected ChosenRelation chRel;
 
-    public FindRelationAction( ChosenRelation chRel ) {
+    public FindRelationAction(ChosenRelation chRel) {
         super(tr("Find"), "relcontext/find", tr("Find a relation"),
                 Shortcut.registerShortcut("reltoolbox:find", tr("Relation Toolbox: {0}", tr("Find a relation")),
-                KeyEvent.VK_F, Shortcut.ALT_CTRL), false);
+                        KeyEvent.VK_F, Shortcut.ALT_CTRL), false);
         this.chRel = chRel;
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         JPanel panel = new JPanel(new BorderLayout());
         final JTextField searchField = new JTextField();
@@ -55,6 +77,6 @@
         relationsList.addMouseListener(new MouseAdapter() {
             @Override
-            public void mouseClicked( MouseEvent e ) {
-                if( e.getClickCount() >= 2 && !relationsList.isSelectionEmpty() ) {
+            public void mouseClicked(MouseEvent e) {
+                if (e.getClickCount() >= 2 && !relationsList.isSelectionEmpty()) {
                     dlg.setVisible(false);
                     optionPane.setValue(JOptionPane.OK_OPTION);
@@ -64,6 +86,7 @@
 
         searchField.addActionListener(new ActionListener() {
-            public void actionPerformed( ActionEvent e ) {
-                if( !relationsList.isSelectionEmpty() ) {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                if (!relationsList.isSelectionEmpty()) {
                     dlg.setVisible(false);
                     optionPane.setValue(JOptionPane.OK_OPTION);
@@ -74,6 +97,7 @@
         searchField.addKeyListener(new KeyAdapter() {
             @Override
-            public void keyTyped( KeyEvent e ) {
+            public void keyTyped(KeyEvent e) {
                 SwingUtilities.invokeLater(new Runnable() {
+                    @Override
                     public void run() {
                         updateRelationData(relationsData, searchField.getText());
@@ -83,16 +107,18 @@
 
             @Override
-            public void keyPressed( KeyEvent e ) {
-                if( shouldForward(e) )
+            public void keyPressed(KeyEvent e) {
+                if (shouldForward(e) ) {
                     relationsList.dispatchEvent(e);
-            }
-
-            @Override
-            public void keyReleased( KeyEvent e ) {
-                if( shouldForward(e) )
+                }
+            }
+
+            @Override
+            public void keyReleased(KeyEvent e) {
+                if (shouldForward(e) ) {
                     relationsList.dispatchEvent(e);
-            }
-
-            private boolean shouldForward( KeyEvent e ) {
+                }
+            }
+
+            private boolean shouldForward(KeyEvent e) {
                 return e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN
                         || e.getKeyCode() == KeyEvent.VK_PAGE_DOWN || e.getKeyCode() == KeyEvent.VK_PAGE_UP
@@ -105,12 +131,12 @@
 
         Object answer = optionPane.getValue();
-        if( answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
-                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION) ) {
+        if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE
+                || (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION))
             return;
-        }
-
-        Relation r = (Relation)relationsList.getSelectedValue();
-        if( r != null )
+
+        Relation r = relationsList.getSelectedValue();
+        if (r != null ) {
             chRel.set(r);
+        }
     }
 
@@ -120,31 +146,33 @@
     }
 
-    protected void updateRelationData( FindRelationListModel data, String filter ) {
+    protected void updateRelationData(FindRelationListModel data, String filter) {
         String[] keywords = filter == null ? new String[0] : filter.split("\\s+");
-        if( keywords.length > 0 ) {
+        if (keywords.length > 0) {
             List<String> filteredKeywords = new ArrayList<>(keywords.length);
-            for( String s : keywords )
-                if( s.length() > 0 )
+            for (String s : keywords )
+                if (s.length() > 0 ) {
                     filteredKeywords.add(s.trim().toLowerCase());
+                }
             keywords = filteredKeywords.toArray(new String[0]);
         }
 
         System.out.println("keywords.length = " + keywords.length);
-        for( int i = 0; i < keywords.length; i++ )
+        for (int i = 0; i < keywords.length; i++ ) {
             System.out.println("keyword["+i+"] = " + keywords[i]);
+        }
 
         List<Relation> relations = new ArrayList<>();
-        if( getEditLayer() != null ) {
-            for( Relation r : getEditLayer().data.getRelations() ) {
-                if( !r.isDeleted() && r.isVisible() && !r.isIncomplete() ) {
+        if (getEditLayer() != null) {
+            for (Relation r : getEditLayer().data.getRelations()) {
+                if (!r.isDeleted() && r.isVisible() && !r.isIncomplete()) {
                     boolean add = true;
-                    for( int i = 0; i < keywords.length && add; i++ ) {
+                    for (int i = 0; i < keywords.length && add; i++) {
                         boolean ok = false;
-                        if( String.valueOf(r.getPrimitiveId().getUniqueId()).contains(keywords[i]) )
+                        if (String.valueOf(r.getPrimitiveId().getUniqueId()).contains(keywords[i]) ) {
                             ok = true;
-                        else {
-                            for( String key : r.keySet() ) {
-                                if( key.contains(keywords[i]) || r.get(key).toLowerCase().contains(keywords[i])
-                                        || tr(r.get(key)).toLowerCase().contains(keywords[i]) ) {
+                        } else {
+                            for (String key : r.keySet()) {
+                                if (key.contains(keywords[i]) || r.get(key).toLowerCase().contains(keywords[i])
+                                        || tr(r.get(key)).toLowerCase().contains(keywords[i])) {
                                     ok = true;
                                     break;
@@ -152,8 +180,11 @@
                             }
                         }
-                        if( !ok ) add = false;
+                        if (!ok ) {
+                            add = false;
+                        }
                     }
-                    if( add )
+                    if (add ) {
                         relations.add(r);
+                    }
                 }
             }
@@ -171,5 +202,5 @@
         private DefaultListSelectionModel selectionModel;
 
-        public FindRelationListModel( DefaultListSelectionModel selectionModel ) {
+        public FindRelationListModel(DefaultListSelectionModel selectionModel) {
             super();
             this.selectionModel = selectionModel;
@@ -190,5 +221,5 @@
 
         @Override
-        public Relation getElementAt( int index ) {
+        public Relation getElementAt(int index) {
             return relations.get(index);
         }
@@ -197,18 +228,21 @@
             int selectedIndex = selectionModel.getMinSelectionIndex();
             Relation sel =  selectedIndex < 0 ? null : getElementAt(selectedIndex);
-            
+
             this.relations.clear();
             selectionModel.clearSelection();
-            if( relations != null )
+            if (relations != null ) {
                 this.relations.addAll(relations);
+            }
             fireIntervalAdded(this, 0, getSize());
 
-            if( sel != null ) {
+            if (sel != null) {
                 selectedIndex = this.relations.indexOf(sel);
-                if( selectedIndex >= 0 )
+                if (selectedIndex >= 0 ) {
                     selectionModel.addSelectionInterval(selectedIndex, selectedIndex);
-            }
-            if( selectionModel.isSelectionEmpty() && !this.relations.isEmpty() )
+                }
+            }
+            if (selectionModel.isSelectionEmpty() && !this.relations.isEmpty() ) {
                 selectionModel.addSelectionInterval(0, 0);
+            }
         }
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/PublicTransportHelper.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/PublicTransportHelper.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/PublicTransportHelper.java	(revision 32395)
@@ -1,9 +1,8 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
-import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.RelationMember;
-import org.openstreetmap.josm.data.osm.Way;
 
 /**
@@ -26,10 +25,10 @@
     public final static String BUS_STOP = "bus_stop";
     public final static String RAILWAY_HALT = "halt";
-    public final static String RAILWAY_STATION = "station";    
-    
+    public final static String RAILWAY_STATION = "station";
+
     private PublicTransportHelper() {
         // Hide default constructor for utils classes
-    }        
-    
+    }
+
     public static String getRoleByMember(RelationMember m) {
         if (isMemberStop(m)) return STOP;
@@ -37,17 +36,17 @@
         return null;
     }
-    
+
     public static boolean isMemberStop(RelationMember m) {
         return isNodeStop(m);   // stop is only node
     }
-    
+
     public static boolean isMemberPlatform(RelationMember m) {
         return isNodePlatform(m) || isWayPlatform(m);
     }
-    
+
     public static boolean isNodeStop(RelationMember m) {
         return isNodeStop(m.getMember());
     }
-    
+
     public static boolean isNodeStop(OsmPrimitive p) {
         if (p.getType() == OsmPrimitiveType.NODE && !p.isIncomplete()) {
@@ -63,9 +62,9 @@
         return false;
     }
-    
+
     public static boolean isNodePlatform(RelationMember m) {
         return isNodePlatform(m.getMember());
     }
-    
+
     public static boolean isNodePlatform(OsmPrimitive p) {
         if (p.getType() == OsmPrimitiveType.NODE && !p.isIncomplete()) {
@@ -87,5 +86,5 @@
         return isWayPlatform(m.getMember());
     }
-    
+
     public static boolean isWayPlatform(OsmPrimitive p) {
         if (p.getType() == OsmPrimitiveType.WAY && !p.isIncomplete()) {
@@ -103,20 +102,19 @@
         return false;
     }
-    
+
     public static boolean isMemberRouteway(RelationMember m) {
         return isWayRouteway(m.getMember());
     }
-    
+
     public static boolean isWayRouteway(OsmPrimitive p) {
-        if (p.getType() == OsmPrimitiveType.WAY && !p.isIncomplete()) {
+        if (p.getType() == OsmPrimitiveType.WAY && !p.isIncomplete())
             return p.hasKey(HIGHWAY) || p.hasKey(RAILWAY);
-        }
         return false;
     }
-    
+
     public static String getNameViaStoparea(RelationMember m) {
         return getNameViaStoparea(m.getMember());
     }
-    
+
     public static String getNameViaStoparea(OsmPrimitive prim) {
         String result = prim.getName();
@@ -125,9 +123,9 @@
         for (OsmPrimitive refOp : prim.getReferrers())
             if (refOp.getType() == OsmPrimitiveType.RELATION
-                && refOp.hasTag(PUBLIC_TRANSPORT, STOP_AREA)) {
+            && refOp.hasTag(PUBLIC_TRANSPORT, STOP_AREA)) {
                 result = refOp.getName();
                 if (result != null) return result;
             }
         return result;
-    }    
+    }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructPolygonAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructPolygonAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructPolygonAction.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
@@ -40,12 +41,12 @@
 public class ReconstructPolygonAction extends AbstractAction implements ChosenRelationListener {
     private ChosenRelation rel;
-    
+
     private static final List<String> IRRELEVANT_KEYS = Arrays.asList(new String[] {
-    "source", "created_by", "note"});
+            "source", "created_by", "note"});
 
-    public ReconstructPolygonAction( ChosenRelation rel ) {
+    public ReconstructPolygonAction(ChosenRelation rel) {
         super(tr("Reconstruct polygon"));
         putValue(SMALL_ICON, ImageProvider.get("dialogs", "filter"));
-    putValue(LONG_DESCRIPTION, "Reconstruct polygon from multipolygon relation");
+        putValue(LONG_DESCRIPTION, "Reconstruct polygon from multipolygon relation");
         this.rel = rel;
         rel.addChosenRelationListener(this);
@@ -53,112 +54,116 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Relation r = rel.get();
-    List<Way> ways = new ArrayList<>();
-    boolean wont = false;
-    for( RelationMember m : r.getMembers() ) {
-        if( m.isWay() )
-        ways.add(m.getWay());
-        else
-        wont = true;
-    }
-    if( wont ) {
-        JOptionPane.showMessageDialog(Main.parent, tr("Multipolygon must consist only of ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE);
-        return;
-    }
-    
-    MultipolygonBuilder mpc = new MultipolygonBuilder();
-    String error = mpc.makeFromWays(ways);
-    if( error != null ) {
-        JOptionPane.showMessageDialog(Main.parent, error);
-        return;
-    }
-    
-    if( !mpc.innerWays.isEmpty() ) {
-        JOptionPane.showMessageDialog(Main.parent, tr("Reconstruction of polygons can be done only from outer ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE);
-        return;
-    }
-    
-    rel.clear();
-    List<Way> newSelection = new ArrayList<>();
-    List<Command> commands = new ArrayList<>();
-        Command c = DeleteCommand.delete(Main.main.getEditLayer(), Collections.singleton(r), true, true);
-        if( c == null )
-            return;
-    commands.add(c);
-    
-    for( JoinedPolygon p : mpc.outerWays ) {
-        // move all tags from relation and common tags from ways
-        Map<String, String> tags = p.ways.get(0).getKeys();
-        List<OsmPrimitive> relations = p.ways.get(0).getReferrers();
-        Set<String> noTags = new HashSet<>(r.keySet());
-        for( int i = 1; i < p.ways.size(); i++ ) {
-        Way w = p.ways.get(i);
-        for( String key : w.keySet() ) {
-            String value = w.get(key);
-            if( !noTags.contains(key) && tags.containsKey(key) && !tags.get(key).equals(value) ) {
-            tags.remove(key);
-            noTags.add(key);
+        List<Way> ways = new ArrayList<>();
+        boolean wont = false;
+        for (RelationMember m : r.getMembers()) {
+            if (m.isWay() ) {
+                ways.add(m.getWay());
+            } else {
+                wont = true;
             }
         }
-        List<OsmPrimitive> referrers = w.getReferrers();
-        for( Iterator<OsmPrimitive> ref1 = relations.iterator(); ref1.hasNext(); )
-            if( !referrers.contains(ref1.next()) )
-            ref1.remove();
+        if (wont) {
+            JOptionPane.showMessageDialog(Main.parent, tr("Multipolygon must consist only of ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE);
+            return;
         }
-        tags.putAll(r.getKeys());
-        tags.remove("type");
-        
-        // then delete ways that are not relevant (do not take part in other relations of have strange tags)
-        Way candidateWay = null;
-        for( Way w : p.ways ) {
-        if( w.getReferrers().equals(relations) ) {
-            // check tags that remain
-            Set<String> keys = new HashSet<>(w.keySet());
-            keys.removeAll(tags.keySet());
-            keys.removeAll(IRRELEVANT_KEYS);
-            if( keys.isEmpty() ) {
-            if( candidateWay == null )
-                candidateWay = w;
-            else {
-                if( candidateWay.isNew() && !w.isNew() ) {
-                // prefer ways that are already in the database
-                Way tmp = w;
-                w = candidateWay;
-                candidateWay = tmp;
+
+        MultipolygonBuilder mpc = new MultipolygonBuilder();
+        String error = mpc.makeFromWays(ways);
+        if (error != null) {
+            JOptionPane.showMessageDialog(Main.parent, error);
+            return;
+        }
+
+        if (!mpc.innerWays.isEmpty()) {
+            JOptionPane.showMessageDialog(Main.parent, tr("Reconstruction of polygons can be done only from outer ways"), tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE);
+            return;
+        }
+
+        rel.clear();
+        List<Way> newSelection = new ArrayList<>();
+        List<Command> commands = new ArrayList<>();
+        Command c = DeleteCommand.delete(Main.main.getEditLayer(), Collections.singleton(r), true, true);
+        if (c == null )
+            return;
+        commands.add(c);
+
+        for (JoinedPolygon p : mpc.outerWays) {
+            // move all tags from relation and common tags from ways
+            Map<String, String> tags = p.ways.get(0).getKeys();
+            List<OsmPrimitive> relations = p.ways.get(0).getReferrers();
+            Set<String> noTags = new HashSet<>(r.keySet());
+            for (int i = 1; i < p.ways.size(); i++) {
+                Way w = p.ways.get(i);
+                for (String key : w.keySet()) {
+                    String value = w.get(key);
+                    if (!noTags.contains(key) && tags.containsKey(key) && !tags.get(key).equals(value)) {
+                        tags.remove(key);
+                        noTags.add(key);
+                    }
                 }
-                commands.add(new DeleteCommand(w));
+                List<OsmPrimitive> referrers = w.getReferrers();
+                for (Iterator<OsmPrimitive> ref1 = relations.iterator(); ref1.hasNext(); )
+                    if (!referrers.contains(ref1.next()) ) {
+                        ref1.remove();
+                    }
             }
+            tags.putAll(r.getKeys());
+            tags.remove("type");
+
+            // then delete ways that are not relevant (do not take part in other relations of have strange tags)
+            Way candidateWay = null;
+            for (Way w : p.ways) {
+                if (w.getReferrers().equals(relations)) {
+                    // check tags that remain
+                    Set<String> keys = new HashSet<>(w.keySet());
+                    keys.removeAll(tags.keySet());
+                    keys.removeAll(IRRELEVANT_KEYS);
+                    if (keys.isEmpty()) {
+                        if (candidateWay == null ) {
+                            candidateWay = w;
+                        } else {
+                            if (candidateWay.isNew() && !w.isNew()) {
+                                // prefer ways that are already in the database
+                                Way tmp = w;
+                                w = candidateWay;
+                                candidateWay = tmp;
+                            }
+                            commands.add(new DeleteCommand(w));
+                        }
+                    }
+                }
             }
+
+            // take the first way, put all nodes into it, making it a closed polygon
+            Way result = candidateWay == null ? new Way() : new Way(candidateWay);
+            result.setNodes(p.nodes);
+            result.addNode(result.firstNode());
+            result.setKeys(tags);
+            newSelection.add(candidateWay == null ? result : candidateWay);
+            commands.add(candidateWay == null ? new AddCommand(result) : new ChangeCommand(candidateWay, result));
         }
-        }
-        
-        // take the first way, put all nodes into it, making it a closed polygon
-        Way result = candidateWay == null ? new Way() : new Way(candidateWay);
-        result.setNodes(p.nodes);
-        result.addNode(result.firstNode());
-        result.setKeys(tags);
-        newSelection.add(candidateWay == null ? result : candidateWay);
-        commands.add(candidateWay == null ? new AddCommand(result) : new ChangeCommand(candidateWay, result));
-    }
-    
+
         Main.main.undoRedo.add(new SequenceCommand(tr("Reconstruct polygons from relation {0}",
-        r.getDisplayName(DefaultNameFormatter.getInstance())), commands));
-    Main.main.getCurrentDataSet().setSelected(newSelection);
+                r.getDisplayName(DefaultNameFormatter.getInstance())), commands));
+        Main.main.getCurrentDataSet().setSelected(newSelection);
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
-    setEnabled(isSuitableRelation(newRelation));
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
+        setEnabled(isSuitableRelation(newRelation));
     }
-    
-    private boolean isSuitableRelation( Relation newRelation ) {
-    if( newRelation == null || !"multipolygon".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0 )
-        return false;
-    else {
-        for( RelationMember m : newRelation.getMembers() )
-        if( "inner".equals(m.getRole()) )
+
+    private boolean isSuitableRelation(Relation newRelation) {
+        if (newRelation == null || !"multipolygon".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0 )
             return false;
-        return true;
-    }
+        else {
+            for (RelationMember m : newRelation.getMembers() )
+                if ("inner".equals(m.getRole()) )
+                    return false;
+            return true;
+        }
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructRouteAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructRouteAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/ReconstructRouteAction.java	(revision 32395)
@@ -1,3 +1,6 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.event.ActionEvent;
@@ -6,7 +9,7 @@
 import java.util.List;
 import java.util.Map;
+
 import javax.swing.AbstractAction;
-import static javax.swing.Action.LONG_DESCRIPTION;
-import static javax.swing.Action.SMALL_ICON;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -21,6 +24,6 @@
 import org.openstreetmap.josm.gui.dialogs.relation.sort.RelationSorter;
 import org.openstreetmap.josm.tools.Geometry;
-import static org.openstreetmap.josm.tools.I18n.tr;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -32,5 +35,5 @@
 public class ReconstructRouteAction  extends AbstractAction implements ChosenRelationListener {
     private final ChosenRelation rel;
-    
+
     public ReconstructRouteAction (ChosenRelation rel) {
         super(tr("Reconstruct route"));
@@ -41,10 +44,11 @@
         setEnabled(isSuitableRelation(rel.get()));
     }
-    
-    public void actionPerformed( ActionEvent e ) {
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Relation r = rel.get();
-        Relation recRel = new Relation(r);        
+        Relation recRel = new Relation(r);
         recRel.removeMembersFor(recRel.getMemberPrimitives());
-        
+
         Map<OsmPrimitive, RelationMember> stopMembers = new LinkedHashMap<>();
         Map<String, List<RelationMember>> platformMembers = new LinkedHashMap<>();
@@ -52,5 +56,5 @@
         List<RelationMember> routeMembers = new ArrayList<>();
         List<RelationMember> wtfMembers = new ArrayList<>();
-        
+
         int mCount = r.getMembersCount();
         for (int i = 0; i < mCount; i++) {
@@ -58,27 +62,33 @@
             if (PublicTransportHelper.isMemberStop(m)) {
                 RelationMember rm = new RelationMember(
-                        m.hasRole() ? m.getRole() : PublicTransportHelper.STOP, 
-                        m.getMember());
+                        m.hasRole() ? m.getRole() : PublicTransportHelper.STOP,
+                                m.getMember());
                 stopMembers.put(rm.getMember(), rm);
             }
             else if (PublicTransportHelper.isMemberPlatform(m)) {
                 RelationMember rm = new RelationMember(
-                        m.hasRole() ? m.getRole() : PublicTransportHelper.PLATFORM, 
-                        m.getMember());
+                        m.hasRole() ? m.getRole() : PublicTransportHelper.PLATFORM,
+                                m.getMember());
                 String platformName = PublicTransportHelper.getNameViaStoparea(rm);
-                if (platformName == null) platformName = "";
-                if (platformMembers.containsKey(platformName)) platformMembers.get(platformName).add(rm);
-                else {
+                if (platformName == null) {
+                    platformName = "";
+                }
+                if (platformMembers.containsKey(platformName)) {
+                    platformMembers.get(platformName).add(rm);
+                } else {
                     List<RelationMember> nList = new ArrayList<>();
                     nList.add(rm);
                     platformMembers.put(platformName, nList);
-                }                
-            }
-            else if (PublicTransportHelper.isMemberRouteway(m)) routeMembers.add(new RelationMember(m));
-            else wtfMembers.add(new RelationMember(m));
-        }
-        
+                }
+            }
+            else if (PublicTransportHelper.isMemberRouteway(m)) {
+                routeMembers.add(new RelationMember(m));
+            } else {
+                wtfMembers.add(new RelationMember(m));
+            }
+        }
+
         routeMembers = RelationSorter.sortMembersByConnectivity(routeMembers);
-        
+
         Node lastNode = null;
         for (int rIndex = 0; rIndex < routeMembers.size(); rIndex++) {
@@ -91,14 +101,17 @@
                         dirForward = true;
                         lastNode = w.lastNode();
-                    } else lastNode = w.firstNode();
+                    } else {
+                        lastNode = w.firstNode();
+                    }
                 } // else one segment - direction unknown
             } else {
-                if (lastNode.equals(w.firstNode())) { dirForward = true; lastNode = w.lastNode(); }
-                else lastNode = w.firstNode();
+                if (lastNode.equals(w.firstNode())) { dirForward = true; lastNode = w.lastNode(); } else {
+                    lastNode = w.firstNode();
+                }
             }
             final int wayNodeBeginIndex = (dirForward ? 0 : w.getNodesCount() - 1);
             final int wayNodeEndIndex = (dirForward ? w.getNodesCount() - 1 : 0);
             final int increment = (dirForward ? 1 : -1);
-            for(int nIndex = wayNodeBeginIndex;
+            for (int nIndex = wayNodeBeginIndex;
                     nIndex != wayNodeEndIndex;
                     nIndex += increment) {
@@ -109,5 +122,7 @@
                         stopMembers.remove(refNode);
                         String stopName = PublicTransportHelper.getNameViaStoparea(refNode);
-                        if (stopName == null) stopName = "";
+                        if (stopName == null) {
+                            stopName = "";
+                        }
                         boolean existsPlatform = platformMembers.containsKey(stopName);
                         if (!existsPlatform) { stopName = ""; } // find of the nameless
@@ -118,5 +133,5 @@
                                 lMember.remove(0);
                             } else {
-                                // choose closest                                
+                                // choose closest
                                 RelationMember candidat = getClosestPlatform(lMember, refNode);
                                 if (candidat != null) {
@@ -125,5 +140,7 @@
                                 }
                             }
-                            if (lMember.isEmpty()) platformMembers.remove(stopName);                            
+                            if (lMember.isEmpty()) {
+                                platformMembers.remove(stopName);
+                            }
                         }
                     }
@@ -131,5 +148,5 @@
             }
         }
-        
+
         for (RelationMember stop : stopMembers.values()) {
             recRel.addMember(stop);
@@ -137,5 +154,5 @@
             boolean existsPlatform = platformMembers.containsKey(stopName);
             if (!existsPlatform) { stopName = ""; } // find of the nameless
-            if (existsPlatform || platformMembers.containsKey(stopName)) {            
+            if (existsPlatform || platformMembers.containsKey(stopName)) {
                 List<RelationMember> lMember = platformMembers.get(stopName);
                 if (lMember.size() == 1) {
@@ -143,5 +160,5 @@
                     lMember.remove(0);
                 } else {
-                    // choose closest                                
+                    // choose closest
                     RelationMember candidat = getClosestPlatform(lMember, stop.getNode());
                     if (candidat != null) {
@@ -150,21 +167,27 @@
                     }
                 }
-                if (lMember.isEmpty()) platformMembers.remove(stopName);                            
-            }
-        }
-        
-        for (List<RelationMember> lPlatforms : platformMembers.values())
-            for (RelationMember platform : lPlatforms)
+                if (lMember.isEmpty()) {
+                    platformMembers.remove(stopName);
+                }
+            }
+        }
+
+        for (List<RelationMember> lPlatforms : platformMembers.values()) {
+            for (RelationMember platform : lPlatforms) {
                 recRel.addMember(platform);
-        
-        for (RelationMember route : routeMembers)
+            }
+        }
+
+        for (RelationMember route : routeMembers) {
             recRel.addMember(route);
-        for (RelationMember wtf : wtfMembers)
-            recRel.addMember(wtf);        
+        }
+        for (RelationMember wtf : wtfMembers) {
+            recRel.addMember(wtf);
+        }
         Command command = new ChangeCommand(r, recRel);
         Main.main.undoRedo.add(command);
     }
-    
-    private static final double maxSqrDistBetweenStopAndPlatform = 2000; // ~ 26m    
+
+    private static final double maxSqrDistBetweenStopAndPlatform = 2000; // ~ 26m
     private RelationMember getClosestPlatform(List<RelationMember> members, Node stop) {
         if (stop == null || members.isEmpty()) return null;
@@ -182,8 +205,8 @@
                 Way way = member.getWay();
                 EastNorth closest = Geometry.closestPointToSegment(
-                                way.firstNode().getEastNorth(), 
-                                way.lastNode().getEastNorth(), 
-                                stop.getEastNorth()
-                );
+                        way.firstNode().getEastNorth(),
+                        way.lastNode().getEastNorth(),
+                        stop.getEastNorth()
+                        );
                 double sqrDist = stop.getEastNorth().distanceSq(closest);
                 if (sqrDist < maxDist) {
@@ -195,9 +218,10 @@
         return result;
     }
- 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
-	setEnabled(isSuitableRelation(newRelation));
-    }    
-    
+
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
+        setEnabled(isSuitableRelation(newRelation));
+    }
+
     private boolean isSuitableRelation (Relation newRelation) {
         return !(newRelation == null || !"route".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0);
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/RelationHelpAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/RelationHelpAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/RelationHelpAction.java	(revision 32395)
@@ -1,5 +1,7 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
 import java.net.HttpURLConnection;
@@ -8,5 +10,7 @@
 import java.util.ArrayList;
 import java.util.List;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -14,4 +18,5 @@
 import org.openstreetmap.josm.tools.LanguageInfo;
 import org.openstreetmap.josm.tools.OpenBrowser;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -20,5 +25,5 @@
     private ChosenRelation rel;
 
-    public RelationHelpAction( ChosenRelation rel ) {
+    public RelationHelpAction(ChosenRelation rel) {
         super();
         putValue(NAME, tr("Open relation wiki page"));
@@ -30,5 +35,6 @@
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
@@ -37,6 +43,7 @@
      * Copypasted from {@link org.openstreetmap.josm.gui.dialogs.properties.PropertiesDialog.HelpAction}.
      */
-    public void actionPerformed( ActionEvent e ) {
-        if( rel.get() == null )
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (rel.get() == null )
             return;
         try {
@@ -55,4 +62,5 @@
 
             Main.worker.execute(new Runnable(){
+                @Override
                 public void run() {
                     try {
@@ -73,5 +81,5 @@
                                         .replace("=", "%3D") /* do not URLencode whole string! */
                                         .replaceFirst("/wiki/", "/w/index.php?redirect=no&title=")
-                                ).toURL().openConnection();
+                                        ).toURL().openConnection();
                                 conn.setConnectTimeout(5000);
 
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectInRelationPanelAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectInRelationPanelAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectInRelationPanelAction.java	(revision 32395)
@@ -1,10 +1,15 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -13,5 +18,5 @@
     private ChosenRelation rel;
 
-    public SelectInRelationPanelAction( ChosenRelation rel ) {
+    public SelectInRelationPanelAction(ChosenRelation rel) {
         super();
         putValue(NAME, tr("Select in relation list"));
@@ -23,6 +28,7 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
-        if( rel.get() != null ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        if (rel.get() != null) {
             Main.map.relationListDialog.selectRelation(rel.get());
             Main.map.relationListDialog.unfurlDialog();
@@ -30,5 +36,6 @@
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectMembersAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectMembersAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectMembersAction.java	(revision 32395)
@@ -1,10 +1,15 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -13,5 +18,5 @@
     private ChosenRelation rel;
 
-    public SelectMembersAction( ChosenRelation rel ) {
+    public SelectMembersAction(ChosenRelation rel) {
         super(tr("Select members"));
         putValue(SMALL_ICON, ImageProvider.get("selectall"));
@@ -21,9 +26,11 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Main.main.getEditLayer().data.setSelected(rel.get() == null ? null : rel.get().getMemberPrimitives());
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectRelationAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SelectRelationAction.java	(revision 32395)
@@ -1,10 +1,15 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
+
 import javax.swing.AbstractAction;
+
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.tools.ImageProvider;
+
 import relcontext.ChosenRelation;
 import relcontext.ChosenRelationListener;
@@ -13,5 +18,5 @@
     private ChosenRelation rel;
 
-    public SelectRelationAction( ChosenRelation rel ) {
+    public SelectRelationAction(ChosenRelation rel) {
         super(tr("Select relation"));
         putValue(SHORT_DESCRIPTION, tr("Select relation in main selection."));
@@ -22,9 +27,11 @@
     }
 
-    public void actionPerformed( ActionEvent e ) {
+    @Override
+    public void actionPerformed(ActionEvent e) {
         Main.main.getEditLayer().data.setSelected(rel.get() == null ? null : rel.get());
     }
 
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
+    @Override
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
         setEnabled(newRelation != null);
     }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SortAndFixAction.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SortAndFixAction.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SortAndFixAction.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
@@ -30,7 +31,7 @@
     private List<RelationFixer> fixers;
 
-    public SortAndFixAction( ChosenRelation rel ) {
+    public SortAndFixAction(ChosenRelation rel) {
         super();
-//        putValue(Action.NAME, "AZ");
+        //        putValue(Action.NAME, "AZ");
         putValue(Action.SMALL_ICON, ImageProvider.get("data", "warning"));
         putValue(Action.SHORT_DESCRIPTION, tr("Fix roles of the chosen relation members"));
@@ -47,5 +48,5 @@
         fixers.add(new PublicTransportFixer()); //public_transport
 
-        for(RelationFixer fix : fixers) {
+        for (RelationFixer fix : fixers) {
             fix.setFixAction(this);
         }
@@ -53,21 +54,22 @@
 
     @Override
-    public void actionPerformed( ActionEvent e ) {
+    public void actionPerformed(ActionEvent e) {
         Command c = fixRelation(rel.get());
-        if( c != null )
+        if (c != null ) {
             Main.main.undoRedo.add(c);
+        }
     }
 
     @Override
-    public void chosenRelationChanged( Relation oldRelation, Relation newRelation ) {
-        setEnabled(newRelation != null && needsFixing( newRelation));
+    public void chosenRelationChanged(Relation oldRelation, Relation newRelation) {
+        setEnabled(newRelation != null && needsFixing(newRelation));
     }
 
-    public boolean needsFixing( Relation rel ) {
+    public boolean needsFixing(Relation rel) {
         return !isIncomplete(rel) && !getFixer(rel).isRelationGood(rel);
     }
 
-    private RelationFixer getFixer( Relation rel ) {
-        for(RelationFixer fixer : fixers)
+    private RelationFixer getFixer(Relation rel) {
+        for (RelationFixer fixer : fixers)
             if (fixer.isFixerApplicable(rel))
                 return fixer;
@@ -75,13 +77,13 @@
     }
 
-    public Command fixRelation( Relation rel ) {
+    public Command fixRelation(Relation rel) {
         return getFixer(rel).fixRelation(rel);
     }
 
-    protected static boolean isIncomplete( Relation r ) {
-        if( r == null || r.isIncomplete() || r.isDeleted() )
+    protected static boolean isIncomplete(Relation r) {
+        if (r == null || r.isIncomplete() || r.isDeleted() )
             return true;
-        for( RelationMember m : r.getMembers())
-            if( m.getMember().isIncomplete() )
+        for (RelationMember m : r.getMembers())
+            if (m.getMember().isIncomplete() )
                 return true;
         return false;
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SplittingMultipolygons.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SplittingMultipolygons.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SplittingMultipolygons.java	(revision 32395)
@@ -1,15 +1,28 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
+import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.geom.Area;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.*;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.ChangeCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.tools.Geometry;
@@ -23,79 +36,82 @@
     private static final String PREF_MULTIPOLY = "reltoolbox.multipolygon.";
 
-    public static boolean canProcess( Collection<Way> ways ) {
-    List<Way> rings = new ArrayList<>();
-    List<Way> arcs = new ArrayList<>();
-    Area a = Main.main.getCurrentDataSet().getDataSourceArea();
-    for( Way way : ways ) {
-        if( way.isDeleted() )
-        return false;
-        for( Node n : way.getNodes() ) {
-            LatLon ll = n.getCoor();
-            if( n.isIncomplete() || (a != null && !a.contains(ll.getX(), ll.getY())) )
+    public static boolean canProcess(Collection<Way> ways) {
+        List<Way> rings = new ArrayList<>();
+        List<Way> arcs = new ArrayList<>();
+        Area a = Main.main.getCurrentDataSet().getDataSourceArea();
+        for (Way way : ways) {
+            if (way.isDeleted() )
                 return false;
-        }
-        if( way.isClosed() )
-        rings.add(way);
-        else
-        arcs.add(way);
-    }
-    
-    // If there are more that one segment, check that they touch rings
-    if( arcs.size() > 1 ) {
-        for( Way segment : arcs ) {
-        boolean found = false;
-        for( Way ring : rings )
-            if( ring.containsNode(segment.firstNode()) && ring.containsNode(segment.lastNode()) )
-            found = true;
-        if( !found )
+            for (Node n : way.getNodes()) {
+                LatLon ll = n.getCoor();
+                if (n.isIncomplete() || (a != null && !a.contains(ll.getX(), ll.getY())) )
+                    return false;
+            }
+            if (way.isClosed() ) {
+                rings.add(way);
+            } else {
+                arcs.add(way);
+            }
+        }
+
+        // If there are more that one segment, check that they touch rings
+        if (arcs.size() > 1) {
+            for (Way segment : arcs) {
+                boolean found = false;
+                for (Way ring : rings )
+                    if (ring.containsNode(segment.firstNode()) && ring.containsNode(segment.lastNode()) ) {
+                        found = true;
+                    }
+                if (!found )
+                    return false;
+            }
+        }
+
+        if (rings.isEmpty() && arcs.isEmpty() )
             return false;
-        }
-    }
-
-    if( rings.isEmpty() && arcs.isEmpty() )
-        return false;
-
-    // check for non-containment of rings
-    for( int i = 0; i < rings.size() - 1; i++ ) {
-        for( int j = i + 1; j < rings.size(); j++ ) {
-        PolygonIntersection intersection = Geometry.polygonIntersection(rings.get(i).getNodes(), rings.get(j).getNodes());
-        if( intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST )
-            return false;
-        }
-    }
-
-    return true;
-    }
-    
-    public static List<Relation> process( Collection<Way> selectedWays ) {
-//    System.out.println("---------------------------------------");
-    List<Relation> result = new ArrayList<>();
-    List<Way> rings = new ArrayList<>();
-    List<Way> arcs = new ArrayList<>();
-    for( Way way : selectedWays ) {
-        if( way.isClosed() )
-        rings.add(way);
-        else
-        arcs.add(way);
-    }
-
-    for( Way ring : rings ) {
-        List<Command> commands = new ArrayList<>();
-        Relation newRelation = SplittingMultipolygons.attachRingToNeighbours(ring, commands);
-        if( newRelation != null && !commands.isEmpty() ) {
-        Main.main.undoRedo.add(commands.get(0));
-        result.add(newRelation);
-        }
-    }
-
-    for( Way arc : arcs) {
-        List<Command> commands = new ArrayList<>();
-        Relation newRelation = SplittingMultipolygons.tryToCloseOneWay(arc, commands);
-        if( newRelation != null && !commands.isEmpty() ) {
-        Main.main.undoRedo.add(commands.get(0));
-        result.add(newRelation);
-        }
-    }
-    return result;
+
+        // check for non-containment of rings
+        for (int i = 0; i < rings.size() - 1; i++) {
+            for (int j = i + 1; j < rings.size(); j++) {
+                PolygonIntersection intersection = Geometry.polygonIntersection(rings.get(i).getNodes(), rings.get(j).getNodes());
+                if (intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST )
+                    return false;
+            }
+        }
+
+        return true;
+    }
+
+    public static List<Relation> process(Collection<Way> selectedWays) {
+        //    System.out.println("---------------------------------------");
+        List<Relation> result = new ArrayList<>();
+        List<Way> rings = new ArrayList<>();
+        List<Way> arcs = new ArrayList<>();
+        for (Way way : selectedWays) {
+            if (way.isClosed() ) {
+                rings.add(way);
+            } else {
+                arcs.add(way);
+            }
+        }
+
+        for (Way ring : rings) {
+            List<Command> commands = new ArrayList<>();
+            Relation newRelation = SplittingMultipolygons.attachRingToNeighbours(ring, commands);
+            if (newRelation != null && !commands.isEmpty()) {
+                Main.main.undoRedo.add(commands.get(0));
+                result.add(newRelation);
+            }
+        }
+
+        for (Way arc : arcs) {
+            List<Command> commands = new ArrayList<>();
+            Relation newRelation = SplittingMultipolygons.tryToCloseOneWay(arc, commands);
+            if (newRelation != null && !commands.isEmpty()) {
+                Main.main.undoRedo.add(commands.get(0));
+                result.add(newRelation);
+            }
+        }
+        return result;
     }
 
@@ -103,12 +119,12 @@
      * Appends "append" to "base" so the closed polygon forms.
      */
-    private static void closePolygon( List<Node> base, List<Node> append ) {
-    if( append.get(0).equals(base.get(0)) && append.get(append.size() - 1).equals(base.get(base.size() - 1)) ) {
-        List<Node> ap2 = new ArrayList<>(append);
-        Collections.reverse(ap2);
-        append = ap2;
-    }
-    base.remove(base.size() - 1);
-    base.addAll(append);
+    private static void closePolygon(List<Node> base, List<Node> append) {
+        if (append.get(0).equals(base.get(0)) && append.get(append.size() - 1).equals(base.get(base.size() - 1))) {
+            List<Node> ap2 = new ArrayList<>(append);
+            Collections.reverse(ap2);
+            append = ap2;
+        }
+        base.remove(base.size() - 1);
+        base.addAll(append);
     }
 
@@ -116,9 +132,9 @@
      * Checks if a middle point between two nodes is inside a polygon. Useful to check if the way is inside.
      */
-    private static boolean segmentInsidePolygon( Node n1, Node n2, List<Node> polygon ) {
-    EastNorth en1 = n1.getEastNorth();
-    EastNorth en2 = n2.getEastNorth();
-    Node testNode = new Node(new EastNorth((en1.east() + en2.east()) / 2.0, (en1.north() + en2.north()) / 2.0));
-    return Geometry.nodeInsidePolygon(testNode, polygon);
+    private static boolean segmentInsidePolygon(Node n1, Node n2, List<Node> polygon) {
+        EastNorth en1 = n1.getEastNorth();
+        EastNorth en2 = n2.getEastNorth();
+        Node testNode = new Node(new EastNorth((en1.east() + en2.east()) / 2.0, (en1.north() + en2.north()) / 2.0));
+        return Geometry.nodeInsidePolygon(testNode, polygon);
     }
 
@@ -130,93 +146,99 @@
      * @return Newly created ways. <b>Warning:</b> if commands is no not, newWays contains {@code w}.
      */
-    public static List<Way> splitWay( Way w, Node n1, Node n2, List<Command> commands ) {
-    List<Node> nodes = new ArrayList<>(w.getNodes());
-    if( w.isClosed() )
-        nodes.remove(nodes.size() - 1);
-    int index1 = nodes.indexOf(n1);
-    int index2 = n2 == null ? -1 : nodes.indexOf(n2);
-    if( index1 > index2 ) {
-        int tmp = index1;
-        index1 = index2;
-        index2 = tmp;
-    }
-    // right now index2 >= index1
-    if( index2 < 1 || index1 >= w.getNodesCount() - 1 || index2 >= w.getNodesCount() )
-        return Collections.emptyList();
-    if( w.isClosed() && (index1 < 0 || index1 == index2 || index1 + w.getNodesCount() == index2) )
-        return Collections.emptyList();
-    
-    // todo: download parent relations!
-
-    // make a list of segments
-    List<List<Node>> chunks = new ArrayList<>(2);
-    List<Node> chunk = new ArrayList<>();
-    for( int i = 0; i < nodes.size(); i++ ) {
-        chunk.add(nodes.get(i));
-        if( (w.isClosed() || chunk.size() > 1) && (i == index1 || i == index2) ) {
+    public static List<Way> splitWay(Way w, Node n1, Node n2, List<Command> commands) {
+        List<Node> nodes = new ArrayList<>(w.getNodes());
+        if (w.isClosed() ) {
+            nodes.remove(nodes.size() - 1);
+        }
+        int index1 = nodes.indexOf(n1);
+        int index2 = n2 == null ? -1 : nodes.indexOf(n2);
+        if (index1 > index2) {
+            int tmp = index1;
+            index1 = index2;
+            index2 = tmp;
+        }
+        // right now index2 >= index1
+        if (index2 < 1 || index1 >= w.getNodesCount() - 1 || index2 >= w.getNodesCount() )
+            return Collections.emptyList();
+        if (w.isClosed() && (index1 < 0 || index1 == index2 || index1 + w.getNodesCount() == index2) )
+            return Collections.emptyList();
+
+        // todo: download parent relations!
+
+        // make a list of segments
+        List<List<Node>> chunks = new ArrayList<>(2);
+        List<Node> chunk = new ArrayList<>();
+        for (int i = 0; i < nodes.size(); i++) {
+            chunk.add(nodes.get(i));
+            if ((w.isClosed() || chunk.size() > 1) && (i == index1 || i == index2)) {
+                chunks.add(chunk);
+                chunk = new ArrayList<>();
+                chunk.add(nodes.get(i));
+            }
+        }
         chunks.add(chunk);
-        chunk = new ArrayList<>();
-        chunk.add(nodes.get(i));
-        }
-    }
-    chunks.add(chunk);
-
-    // for closed way ignore the way boundary
-    if( w.isClosed() ) {
-        chunks.get(chunks.size() - 1).addAll(chunks.get(0));
-        chunks.remove(0);
-    } else if( chunks.get(chunks.size() - 1).size() < 2 )
-        chunks.remove(chunks.size() - 1);
-
-    // todo remove debug: show chunks array contents
-    /*for( List<Node> c1 : chunks ) {
-    for( Node cn1 : c1 )
+
+        // for closed way ignore the way boundary
+        if (w.isClosed()) {
+            chunks.get(chunks.size() - 1).addAll(chunks.get(0));
+            chunks.remove(0);
+        } else if (chunks.get(chunks.size() - 1).size() < 2 ) {
+            chunks.remove(chunks.size() - 1);
+        }
+
+        // todo remove debug: show chunks array contents
+        /*for (List<Node> c1 : chunks) {
+    for (Node cn1 : c1 )
     System.out.print(cn1.getId() + ",");
     System.out.println();
     }*/
 
-    // build a map of referencing relations
-    Map<Relation, Integer> references = new HashMap<>();
-    List<Command> relationCommands = new ArrayList<>();
-    for( OsmPrimitive p : w.getReferrers() ) {
-        if( p instanceof Relation ) {
-        Relation rel = commands == null ? (Relation)p : new Relation((Relation)p);
-        if( commands != null )
-            relationCommands.add(new ChangeCommand((Relation)p, rel));
-        for( int i = 0; i < rel.getMembersCount(); i++ )
-            if( rel.getMember(i).getMember().equals(w) )
-            references.put(rel, Integer.valueOf(i));
-        }
-    }
-
-    // build ways
-    List<Way> result = new ArrayList<>();
-    Way updatedWay = commands == null ? w : new Way(w);
-    updatedWay.setNodes(chunks.get(0));
-    if( commands != null ) {
-        commands.add(new ChangeCommand(w, updatedWay));
-        result.add(updatedWay);
-    }
-
-    for( int i = 1; i < chunks.size(); i++ ) {
-        List<Node> achunk = chunks.get(i);
-        Way newWay = new Way();
-        newWay.setKeys(w.getKeys());
-        result.add(newWay);
-        for( Relation rel : references.keySet() ) {
-        int relIndex = references.get(rel);
-        rel.addMember(relIndex + 1, new RelationMember(rel.getMember(relIndex).getRole(), newWay));
-        }
-        newWay.setNodes(achunk);
-        if( commands != null )
-        commands.add(new AddCommand(newWay));
-    }
-    if( commands != null )
-        commands.addAll(relationCommands);
-    return result;
-    }
-
-    public static List<Way> splitWay( Way w, Node n1, Node n2 ) {
-    return splitWay(w, n1, n2, null);
+        // build a map of referencing relations
+        Map<Relation, Integer> references = new HashMap<>();
+        List<Command> relationCommands = new ArrayList<>();
+        for (OsmPrimitive p : w.getReferrers()) {
+            if (p instanceof Relation) {
+                Relation rel = commands == null ? (Relation)p : new Relation((Relation)p);
+                if (commands != null ) {
+                    relationCommands.add(new ChangeCommand(p, rel));
+                }
+                for (int i = 0; i < rel.getMembersCount(); i++ )
+                    if (rel.getMember(i).getMember().equals(w) ) {
+                        references.put(rel, Integer.valueOf(i));
+                    }
+            }
+        }
+
+        // build ways
+        List<Way> result = new ArrayList<>();
+        Way updatedWay = commands == null ? w : new Way(w);
+        updatedWay.setNodes(chunks.get(0));
+        if (commands != null) {
+            commands.add(new ChangeCommand(w, updatedWay));
+            result.add(updatedWay);
+        }
+
+        for (int i = 1; i < chunks.size(); i++) {
+            List<Node> achunk = chunks.get(i);
+            Way newWay = new Way();
+            newWay.setKeys(w.getKeys());
+            result.add(newWay);
+            for (Relation rel : references.keySet()) {
+                int relIndex = references.get(rel);
+                rel.addMember(relIndex + 1, new RelationMember(rel.getMember(relIndex).getRole(), newWay));
+            }
+            newWay.setNodes(achunk);
+            if (commands != null ) {
+                commands.add(new AddCommand(newWay));
+            }
+        }
+        if (commands != null ) {
+            commands.addAll(relationCommands);
+        }
+        return result;
+    }
+
+    public static List<Way> splitWay(Way w, Node n1, Node n2) {
+        return splitWay(w, n1, n2, null);
     }
 
@@ -224,66 +246,69 @@
      * Find a way the tips of a segment, ensure it's in a multipolygon and try to close the relation.
      */
-    public static Relation tryToCloseOneWay( Way segment, List<Command> resultingCommands ) {
-    if( segment.isClosed() || segment.isIncomplete() )
-        return null;
-
-    List<Way> ways = intersection(
-        OsmPrimitive.getFilteredList(segment.firstNode().getReferrers(), Way.class),
-        OsmPrimitive.getFilteredList(segment.lastNode().getReferrers(), Way.class));
-    ways.remove(segment);
-    for( Iterator<Way> iter = ways.iterator(); iter.hasNext(); ) {
-        boolean save = false;
-        for( OsmPrimitive ref : iter.next().getReferrers() )
-        if( ref instanceof Relation && ((Relation)ref).isMultipolygon() && !ref.isDeleted() )
-            save = true;
-        if( !save )
-        iter.remove();
-    }
-    if( ways.isEmpty() )
-        return null; // well...
-    Way target = ways.get(0);
-
-    // time to create a new multipolygon relation and a command stack
-    List<Command> commands = new ArrayList<>();
-    Relation newRelation = new Relation();
-    newRelation.put("type", "multipolygon");
-    newRelation.addMember(new RelationMember("outer", segment));
-    Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
-    Way segmentCopy = new Way(segment);
-    boolean changed = false;
-    for( String key : segmentCopy.keySet() ) {
-        if( !linearTags.contains(key) ) {
-        newRelation.put(key, segmentCopy.get(key));
-        segmentCopy.remove(key);
-        changed = true;
-        }
-    }
-    if( changed )
-        commands.add(new ChangeCommand(segment, segmentCopy));
-
-    // now split the way, at last
-    List<Way> newWays = new ArrayList<>(splitWay(target, segment.firstNode(), segment.lastNode(), commands));
-
-    Way addingWay = null;
-    if( target.isClosed() ) {
-        Way utarget = newWays.get(1);
-        Way alternate = newWays.get(0);
-        List<Node> testRing = new ArrayList<>(segment.getNodes());
-        closePolygon(testRing, utarget.getNodes());
-        addingWay = segmentInsidePolygon(alternate.getNode(0), alternate.getNode(1), testRing) ? alternate : utarget;
-    } else {
-        for( Way w : newWays ) {
-        if( (w.firstNode().equals(segment.firstNode()) && w.lastNode().equals(segment.lastNode()))
-            || (w.firstNode().equals(segment.lastNode()) && w.lastNode().equals(segment.firstNode())) ) {
-            addingWay = w;
-            break;
-        }
-        }
-    }
-    newRelation.addMember(new RelationMember("outer", addingWay.getUniqueId() == target.getUniqueId() ? target : addingWay));
-    commands.add(new AddCommand(newRelation));
-    resultingCommands.add(new SequenceCommand(tr("Complete multipolygon for way {0}",
-        DefaultNameFormatter.getInstance().format(segment)), commands));
-    return newRelation;
+    public static Relation tryToCloseOneWay(Way segment, List<Command> resultingCommands) {
+        if (segment.isClosed() || segment.isIncomplete() )
+            return null;
+
+        List<Way> ways = intersection(
+                OsmPrimitive.getFilteredList(segment.firstNode().getReferrers(), Way.class),
+                OsmPrimitive.getFilteredList(segment.lastNode().getReferrers(), Way.class));
+        ways.remove(segment);
+        for (Iterator<Way> iter = ways.iterator(); iter.hasNext();) {
+            boolean save = false;
+            for (OsmPrimitive ref : iter.next().getReferrers() )
+                if (ref instanceof Relation && ((Relation)ref).isMultipolygon() && !ref.isDeleted() ) {
+                    save = true;
+                }
+            if (!save ) {
+                iter.remove();
+            }
+        }
+        if (ways.isEmpty() )
+            return null; // well...
+        Way target = ways.get(0);
+
+        // time to create a new multipolygon relation and a command stack
+        List<Command> commands = new ArrayList<>();
+        Relation newRelation = new Relation();
+        newRelation.put("type", "multipolygon");
+        newRelation.addMember(new RelationMember("outer", segment));
+        Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
+        Way segmentCopy = new Way(segment);
+        boolean changed = false;
+        for (String key : segmentCopy.keySet()) {
+            if (!linearTags.contains(key)) {
+                newRelation.put(key, segmentCopy.get(key));
+                segmentCopy.remove(key);
+                changed = true;
+            }
+        }
+        if (changed ) {
+            commands.add(new ChangeCommand(segment, segmentCopy));
+        }
+
+        // now split the way, at last
+        List<Way> newWays = new ArrayList<>(splitWay(target, segment.firstNode(), segment.lastNode(), commands));
+
+        Way addingWay = null;
+        if (target.isClosed()) {
+            Way utarget = newWays.get(1);
+            Way alternate = newWays.get(0);
+            List<Node> testRing = new ArrayList<>(segment.getNodes());
+            closePolygon(testRing, utarget.getNodes());
+            addingWay = segmentInsidePolygon(alternate.getNode(0), alternate.getNode(1), testRing) ? alternate : utarget;
+        } else {
+            for (Way w : newWays) {
+                if ((w.firstNode().equals(segment.firstNode()) && w.lastNode().equals(segment.lastNode()))
+                        || (w.firstNode().equals(segment.lastNode()) && w.lastNode().equals(segment.firstNode()))) {
+                    addingWay = w;
+                    break;
+                }
+            }
+        }
+        newRelation.addMember(new RelationMember("outer", addingWay.getUniqueId() == target.getUniqueId() ? target : addingWay));
+        commands.add(new AddCommand(newRelation));
+        resultingCommands.add(new SequenceCommand(tr("Complete multipolygon for way {0}",
+                DefaultNameFormatter.getInstance().format(segment)), commands));
+        return newRelation;
     }
 
@@ -291,66 +316,71 @@
      * Returns all elements from {@code list1} that are in {@code list2}.
      */
-    private static <T> List<T> intersection( Collection<T> list1, Collection<T> list2 ) {
-    List<T> result = new ArrayList<>();
-    for( T item : list1 )
-        if( list2.contains(item) )
-        result.add(item);
-    return result;
-    }
-    
+    private static <T> List<T> intersection(Collection<T> list1, Collection<T> list2) {
+        List<T> result = new ArrayList<>();
+        for (T item : list1 )
+            if (list2.contains(item) ) {
+                result.add(item);
+            }
+        return result;
+    }
+
     /**
      * Make a multipolygon out of the ring, but split it to attach to neighboring multipolygons.
      */
-    public static Relation attachRingToNeighbours( Way ring, List<Command> resultingCommands ) {
-    if( !ring.isClosed() || ring.isIncomplete() )
-        return null;
-    Map<Way, Boolean> touchingWays = new HashMap<>();
-    for( Node n : ring.getNodes() ) {
-        for( OsmPrimitive p : n.getReferrers() ) {
-        if( p instanceof Way && !p.equals(ring) ) {
-            for( OsmPrimitive r : p.getReferrers() ) {
-            if( r instanceof Relation && ((Relation)r).hasKey("type") && ((Relation)r).get("type").equals("multipolygon") ) {
-                if( touchingWays.containsKey((Way)p) )
-                touchingWays.put((Way)p, Boolean.TRUE);
-                else
-                touchingWays.put((Way)p, Boolean.FALSE);
-                break;
-            }
-            }
-        }
-        }
-    }
-    
-    List<TheRing> otherWays = new ArrayList<>();
-    for( Way w : touchingWays.keySet() )
-        if( touchingWays.get(w) ) {
-        otherWays.add(new TheRing(w));
-//        System.out.println("Touching ring: " + otherWays.get(otherWays.size()-1));
-        }
-    
-//    for( Iterator<Way> keys = touchingWays.keySet().iterator(); keys.hasNext(); ) {
-//        if( !touchingWays.get(keys.next()) )
-//        keys.remove();
-//    }
-    
-    // now touchingWays has only ways that touch the ring twice
-    List<Command> commands = new ArrayList<>();
-    TheRing theRing = new TheRing(ring); // this is actually useful
-    
-    for( TheRing otherRing : otherWays )
-        theRing.collide(otherRing);
-    
-    theRing.putSourceWayFirst();
-    for( TheRing otherRing : otherWays )
-        otherRing.putSourceWayFirst();
-    
-    Map<Relation, Relation> relationCache = new HashMap<>();
-    for( TheRing otherRing : otherWays )
-        commands.addAll(otherRing.getCommands(false, relationCache));
-    commands.addAll(theRing.getCommands(relationCache));
-    TheRing.updateCommandsWithRelations(commands, relationCache);
-    resultingCommands.add(new SequenceCommand(tr("Complete multipolygon for way {0}",
-        DefaultNameFormatter.getInstance().format(ring)), commands));
-    return theRing.getRelation();
+    public static Relation attachRingToNeighbours(Way ring, List<Command> resultingCommands) {
+        if (!ring.isClosed() || ring.isIncomplete() )
+            return null;
+        Map<Way, Boolean> touchingWays = new HashMap<>();
+        for (Node n : ring.getNodes()) {
+            for (OsmPrimitive p : n.getReferrers()) {
+                if (p instanceof Way && !p.equals(ring)) {
+                    for (OsmPrimitive r : p.getReferrers()) {
+                        if (r instanceof Relation && ((Relation)r).hasKey("type") && ((Relation)r).get("type").equals("multipolygon")) {
+                            if (touchingWays.containsKey(p) ) {
+                                touchingWays.put((Way)p, Boolean.TRUE);
+                            } else {
+                                touchingWays.put((Way)p, Boolean.FALSE);
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        List<TheRing> otherWays = new ArrayList<>();
+        for (Way w : touchingWays.keySet() )
+            if (touchingWays.get(w)) {
+                otherWays.add(new TheRing(w));
+                //        System.out.println("Touching ring: " + otherWays.get(otherWays.size()-1));
+            }
+
+        //    for (Iterator<Way> keys = touchingWays.keySet().iterator(); keys.hasNext();) {
+        //        if (!touchingWays.get(keys.next()) )
+        //        keys.remove();
+        //    }
+
+        // now touchingWays has only ways that touch the ring twice
+        List<Command> commands = new ArrayList<>();
+        TheRing theRing = new TheRing(ring); // this is actually useful
+
+        for (TheRing otherRing : otherWays ) {
+            theRing.collide(otherRing);
+        }
+
+        theRing.putSourceWayFirst();
+        for (TheRing otherRing : otherWays ) {
+            otherRing.putSourceWayFirst();
+        }
+
+        Map<Relation, Relation> relationCache = new HashMap<>();
+        for (TheRing otherRing : otherWays ) {
+            commands.addAll(otherRing.getCommands(false, relationCache));
+        }
+        commands.addAll(theRing.getCommands(relationCache));
+        TheRing.updateCommandsWithRelations(commands, relationCache);
+        resultingCommands.add(new SequenceCommand(tr("Complete multipolygon for way {0}",
+                DefaultNameFormatter.getInstance().format(ring)), commands));
+        return theRing.getRelation();
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.actions;
 
@@ -25,5 +26,5 @@
  * One ring that contains segments forming an outer way of multipolygon.
  * This class is used in {@link CreateMultipolygonAction#makeManySimpleMultipolygons(java.util.Collection)}.
- * 
+ *
  * @author Zverik
  */
@@ -35,31 +36,31 @@
     private Relation relation = null;
 
-    public TheRing( Way source ) {
-    this.source = source;
-    segments = new ArrayList<>(1);
-    segments.add(new RingSegment(source));
-    }
-    
-    public static boolean areAllOfThoseRings( Collection<Way> ways ) {
-    List<Way> rings = new ArrayList<>();
-    for( Way way : ways ) {
-        if( way.isClosed() )
-        rings.add(way);
-        else
-        return false;
-    }
-    if( rings.isEmpty() || ways.size() == 1 )
-        return false;
-
-    // check for non-containment of rings
-    for( int i = 0; i < rings.size() - 1; i++ ) {
-        for( int j = i + 1; j < rings.size(); j++ ) {
-        PolygonIntersection intersection = Geometry.polygonIntersection(rings.get(i).getNodes(), rings.get(j).getNodes());
-        if( intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST )
+    public TheRing(Way source) {
+        this.source = source;
+        segments = new ArrayList<>(1);
+        segments.add(new RingSegment(source));
+    }
+
+    public static boolean areAllOfThoseRings(Collection<Way> ways) {
+        List<Way> rings = new ArrayList<>();
+        for (Way way : ways) {
+            if (way.isClosed() ) {
+                rings.add(way);
+            } else
+                return false;
+        }
+        if (rings.isEmpty() || ways.size() == 1 )
             return false;
-        }
-    }
-
-    return true;
+
+        // check for non-containment of rings
+        for (int i = 0; i < rings.size() - 1; i++) {
+            for (int j = i + 1; j < rings.size(); j++) {
+                PolygonIntersection intersection = Geometry.polygonIntersection(rings.get(i).getNodes(), rings.get(j).getNodes());
+                if (intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST )
+                    return false;
+            }
+        }
+
+        return true;
     }
 
@@ -68,142 +69,151 @@
      * @return list of new relations.
      */
-    public static List<Relation> makeManySimpleMultipolygons( Collection<Way> selection, List<Command> commands ) {
-    log("---------------------------------------");
-    List<TheRing> rings = new ArrayList<>(selection.size());
-    for( Way w : selection )
-        rings.add(new TheRing(w));
-    for( int i = 0; i < rings.size() - 1; i++ )
-        for( int j = i + 1; j < rings.size(); j++ )
-        rings.get(i).collide(rings.get(j));
-    redistributeSegments(rings);
-    List<Relation> relations = new ArrayList<>();
-    Map<Relation, Relation> relationCache = new HashMap<>();
-    for( TheRing r : rings ) {
-        commands.addAll(r.getCommands(relationCache));
-        relations.add(r.getRelation());
-    }
-    updateCommandsWithRelations(commands, relationCache);
-    return relations;
-    }
-
-    public void collide( TheRing other ) {
-    boolean collideNoted = false;
-    for( int i = 0; i < segments.size(); i++ ) {
-        RingSegment segment1 = segments.get(i);
-        if( !segment1.isReference() ) {
-        for( int j = 0; j < other.segments.size(); j++ ) {
-            RingSegment segment2 = other.segments.get(j);
-            if( !segment2.isReference() ) {
-            log("Comparing " + segment1 + " and " + segment2);
-            Node[] split = getSplitNodes(segment1.getNodes(), segment2.getNodes(), segment1.isRing(), segment2.isRing());
-            if( split != null ) {
-                if( !collideNoted ) {
-                log("Rings for ways " + source.getUniqueId() + " and " + other.source.getUniqueId() + " collide.");
-                collideNoted = true;
-                }
-                RingSegment segment = splitRingAt(i, split[0], split[1]);
-                RingSegment otherSegment = other.splitRingAt(j, split[2], split[3]);
-                if( !areSegmentsEqual(segment, otherSegment) )
-                throw new IllegalArgumentException("Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment);
-                segment.makeReference(otherSegment);
-            }
-            }
-            if( segment1.isReference() )
-            break;
-        }
-        }
-    }
-    }
-    
+    public static List<Relation> makeManySimpleMultipolygons(Collection<Way> selection, List<Command> commands) {
+        log("---------------------------------------");
+        List<TheRing> rings = new ArrayList<>(selection.size());
+        for (Way w : selection ) {
+            rings.add(new TheRing(w));
+        }
+        for (int i = 0; i < rings.size() - 1; i++ ) {
+            for (int j = i + 1; j < rings.size(); j++ ) {
+                rings.get(i).collide(rings.get(j));
+            }
+        }
+        redistributeSegments(rings);
+        List<Relation> relations = new ArrayList<>();
+        Map<Relation, Relation> relationCache = new HashMap<>();
+        for (TheRing r : rings) {
+            commands.addAll(r.getCommands(relationCache));
+            relations.add(r.getRelation());
+        }
+        updateCommandsWithRelations(commands, relationCache);
+        return relations;
+    }
+
+    public void collide(TheRing other) {
+        boolean collideNoted = false;
+        for (int i = 0; i < segments.size(); i++) {
+            RingSegment segment1 = segments.get(i);
+            if (!segment1.isReference()) {
+                for (int j = 0; j < other.segments.size(); j++) {
+                    RingSegment segment2 = other.segments.get(j);
+                    if (!segment2.isReference()) {
+                        log("Comparing " + segment1 + " and " + segment2);
+                        Node[] split = getSplitNodes(segment1.getNodes(), segment2.getNodes(), segment1.isRing(), segment2.isRing());
+                        if (split != null) {
+                            if (!collideNoted) {
+                                log("Rings for ways " + source.getUniqueId() + " and " + other.source.getUniqueId() + " collide.");
+                                collideNoted = true;
+                            }
+                            RingSegment segment = splitRingAt(i, split[0], split[1]);
+                            RingSegment otherSegment = other.splitRingAt(j, split[2], split[3]);
+                            if (!areSegmentsEqual(segment, otherSegment) )
+                                throw new IllegalArgumentException("Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment);
+                            segment.makeReference(otherSegment);
+                        }
+                    }
+                    if (segment1.isReference() ) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Returns array of {start1, last1, start2, last2} or null if there is no common nodes.
      */
-    public static Node[] getSplitNodes( List<Node> nodes1, List<Node> nodes2, boolean isRing1, boolean isRing2 ) {
-    int pos = 0;
-    while( pos < nodes1.size() && !nodes2.contains(nodes1.get(pos)) )
-        pos++;
-    boolean collideFound = pos == nodes1.size();
-    if( pos == 0 && isRing1 ) {
-        // rewind a bit
-        pos = nodes1.size() - 1;
-        while( pos > 0 && nodes2.contains(nodes1.get(pos)) )
-        pos--;
-        if( pos == 0 && nodes1.size() == nodes2.size() ) {
-        JOptionPane.showMessageDialog(Main.parent, "Two rings are equal, and this must not be.", "Multipolygon from rings", JOptionPane.ERROR_MESSAGE);
+    public static Node[] getSplitNodes(List<Node> nodes1, List<Node> nodes2, boolean isRing1, boolean isRing2) {
+        int pos = 0;
+        while(pos < nodes1.size() && !nodes2.contains(nodes1.get(pos)) ) {
+            pos++;
+        }
+        boolean collideFound = pos == nodes1.size();
+        if (pos == 0 && isRing1) {
+            // rewind a bit
+            pos = nodes1.size() - 1;
+            while(pos > 0 && nodes2.contains(nodes1.get(pos)) ) {
+                pos--;
+            }
+            if (pos == 0 && nodes1.size() == nodes2.size()) {
+                JOptionPane.showMessageDialog(Main.parent, "Two rings are equal, and this must not be.", "Multipolygon from rings", JOptionPane.ERROR_MESSAGE);
+                return null;
+            }
+            pos = pos == nodes1.size() - 1 ? 0 : pos + 1;
+        }
+        int firstPos = isRing1 ? pos : nodes1.size();
+        while(!collideFound) {
+            log("pos=" + pos);
+            int start1 = pos;
+            int start2 = nodes2.indexOf(nodes1.get(start1));
+            int last1 = incrementBy(start1, 1, nodes1.size(), isRing1);
+            int last2 = start2;
+            int increment2 = 0;
+            if (last1 >= 0) {
+                last2 = incrementBy(start2, -1, nodes2.size(), isRing2);
+                if (last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) ) {
+                    increment2 = -1;
+                } else {
+                    last2 = incrementBy(start2, 1, nodes2.size(), isRing2);
+                    if (last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) ) {
+                        increment2 = 1;
+                    }
+                }
+            }
+            log("last1=" + last1 + " last2=" + last2 + " increment2=" + increment2);
+            if (increment2 != 0) {
+                // find the first nodes
+                boolean reachedEnd = false;
+                while(!reachedEnd) {
+                    int newLast1 = incrementBy(last1, 1, nodes1.size(), isRing1);
+                    int newLast2 = incrementBy(last2, increment2, nodes2.size(), isRing2);
+                    if (newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2)) ) {
+                        reachedEnd = true;
+                    } else {
+                        last1 = newLast1;
+                        last2 = newLast2;
+                    }
+                }
+                log("last1=" + last1 + " last2=" + last2);
+                if (increment2 < 0) {
+                    int tmp = start2;
+                    start2 = last2;
+                    last2 = tmp;
+                }
+                return new Node[] {nodes1.get(start1), nodes1.get(last1), nodes2.get(start2), nodes2.get(last2)};
+            } else {
+                pos = last1;
+                while(pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos)) ) {
+                    pos = incrementBy(pos, 1, nodes1.size(), isRing1);
+                }
+                if (pos < 0 || pos == firstPos || !nodes2.contains(nodes1.get(pos)) ) {
+                    collideFound = true;
+                }
+            }
+        }
         return null;
-        }
-        pos = pos == nodes1.size() - 1 ? 0 : pos + 1;
-    }
-    int firstPos = isRing1 ? pos : nodes1.size();
-    while( !collideFound ) {
-        log("pos=" + pos);
-        int start1 = pos;
-        int start2 = nodes2.indexOf(nodes1.get(start1));
-        int last1 = incrementBy(start1, 1, nodes1.size(), isRing1);
-        int last2 = start2;
-        int increment2 = 0;
-        if( last1 >= 0 ) {
-        last2 = incrementBy(start2, -1, nodes2.size(), isRing2);
-        if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
-            increment2 = -1;
-        else {
-            last2 = incrementBy(start2, 1, nodes2.size(), isRing2);
-            if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
-            increment2 = 1;
-        }
-        }
-        log("last1=" + last1 + " last2=" + last2 + " increment2=" + increment2);
-        if( increment2 != 0 ) {
-        // find the first nodes
-        boolean reachedEnd = false;
-        while( !reachedEnd ) {
-            int newLast1 = incrementBy(last1, 1, nodes1.size(), isRing1);
-            int newLast2 = incrementBy(last2, increment2, nodes2.size(), isRing2);
-            if( newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2)) )
-            reachedEnd = true;
-            else {
-            last1 = newLast1;
-            last2 = newLast2;
-            }
-        }
-        log("last1=" + last1 + " last2=" + last2);
-        if( increment2 < 0 ) {
-            int tmp = start2;
-            start2 = last2;
-            last2 = tmp;
-        }
-        return new Node[] {nodes1.get(start1), nodes1.get(last1), nodes2.get(start2), nodes2.get(last2)};
-        } else {
-        pos = last1;
-        while( pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos)) )
-            pos = incrementBy(pos, 1, nodes1.size(), isRing1);
-        if( pos < 0 || pos == firstPos || !nodes2.contains(nodes1.get(pos)) )
-            collideFound = true;
-        }
-    }
-    return null;
-    }
-    
-    private static int incrementBy( int value, int increment, int limit1, boolean isRing ) {
-    int result = value + increment;
-    if( result < 0 )
-        return isRing ? result + limit1 : -1;
-    else if( result >= limit1 )
-        return isRing ? result - limit1 : -1;
-    else
-        return result;
-    }
-    
-    private boolean areSegmentsEqual( RingSegment seg1, RingSegment seg2 ) {
-    List<Node> nodes1 = seg1.getNodes();
-    List<Node> nodes2 = seg2.getNodes();
-    int size = nodes1.size();
-    if( size != nodes2.size() )
-        return false;
-    boolean reverse = size > 1 && !nodes1.get(0).equals(nodes2.get(0));
-    for( int i = 0; i < size; i++ )
-        if( !nodes1.get(i).equals(nodes2.get(reverse ? size-1-i : i)) )
-        return false;
-    return true;
+    }
+
+    private static int incrementBy(int value, int increment, int limit1, boolean isRing) {
+        int result = value + increment;
+        if (result < 0 )
+            return isRing ? result + limit1 : -1;
+        else if (result >= limit1 )
+            return isRing ? result - limit1 : -1;
+        else
+            return result;
+    }
+
+    private boolean areSegmentsEqual(RingSegment seg1, RingSegment seg2) {
+        List<Node> nodes1 = seg1.getNodes();
+        List<Node> nodes2 = seg2.getNodes();
+        int size = nodes1.size();
+        if (size != nodes2.size() )
+            return false;
+        boolean reverse = size > 1 && !nodes1.get(0).equals(nodes2.get(0));
+        for (int i = 0; i < size; i++ )
+            if (!nodes1.get(i).equals(nodes2.get(reverse ? size-1-i : i)) )
+                return false;
+        return true;
     }
 
@@ -212,29 +222,31 @@
      * @return The segment between nodes.
      */
-    private RingSegment splitRingAt( int segmentIndex, Node n1, Node n2 ) {
-    if( n1.equals(n2) )
-        throw new IllegalArgumentException("Both nodes are equal, id=" + n1.getUniqueId());
-    RingSegment segment = segments.get(segmentIndex);
-    boolean isRing = segment.isRing();
-    log("Split segment " + segment + " at nodes " + n1.getUniqueId() + " and " + n2.getUniqueId());
-    boolean reversed = segment.getNodes().indexOf(n2) < segment.getNodes().indexOf(n1);
-    if( reversed && !isRing ) {
-        // order nodes
-        Node tmp = n1;
-        n1 = n2;
-        n2 = tmp;
-    }
-    RingSegment secondPart = isRing ? segment.split(n1, n2) : segment.split(n1);
-    // if secondPart == null, then n1 == firstNode
-    RingSegment thirdPart = isRing ? null : secondPart == null ? segment.split(n2) : secondPart.split(n2);
-    // if secondPart == null, then thirdPart is between n1 and n2
-    // otherwise, thirdPart is between n2 and lastNode
-    // if thirdPart == null, then n2 == lastNode
-    int pos = segmentIndex + 1;
-    if( secondPart != null )
-        segments.add(pos++, secondPart);
-    if( thirdPart != null )
-        segments.add(pos++, thirdPart);
-    return isRing || secondPart == null ? segment : secondPart;
+    private RingSegment splitRingAt(int segmentIndex, Node n1, Node n2) {
+        if (n1.equals(n2) )
+            throw new IllegalArgumentException("Both nodes are equal, id=" + n1.getUniqueId());
+        RingSegment segment = segments.get(segmentIndex);
+        boolean isRing = segment.isRing();
+        log("Split segment " + segment + " at nodes " + n1.getUniqueId() + " and " + n2.getUniqueId());
+        boolean reversed = segment.getNodes().indexOf(n2) < segment.getNodes().indexOf(n1);
+        if (reversed && !isRing) {
+            // order nodes
+            Node tmp = n1;
+            n1 = n2;
+            n2 = tmp;
+        }
+        RingSegment secondPart = isRing ? segment.split(n1, n2) : segment.split(n1);
+        // if secondPart == null, then n1 == firstNode
+        RingSegment thirdPart = isRing ? null : secondPart == null ? segment.split(n2) : secondPart.split(n2);
+        // if secondPart == null, then thirdPart is between n1 and n2
+        // otherwise, thirdPart is between n2 and lastNode
+        // if thirdPart == null, then n2 == lastNode
+        int pos = segmentIndex + 1;
+        if (secondPart != null ) {
+            segments.add(pos++, secondPart);
+        }
+        if (thirdPart != null ) {
+            segments.add(pos++, thirdPart);
+        }
+        return isRing || secondPart == null ? segment : secondPart;
     }
 
@@ -242,137 +254,151 @@
      * Tries to arrange segments in order for each ring to have at least one.
      * Also, sets source way for all rings.
-     * 
+     *
      * If this method is not called, do not forget to call {@link #putSourceWayFirst()} for all rings.
      */
-    public static void redistributeSegments( List<TheRing> rings ) {
-    // build segments map
-    Map<RingSegment, TheRing> segmentMap = new HashMap<>();
-    for( TheRing ring : rings )
-        for( RingSegment seg : ring.segments )
-        if( !seg.isReference() )
-            segmentMap.put(seg, ring);
-
-    // rearrange references
-    for( int i = 0; i < rings.size(); i++ ) {
-        TheRing ring = rings.get(i);
-        if( ring.countNonReferenceSegments() == 0 ) {
-        // need to find one non-reference segment
-        for( RingSegment seg : ring.segments ) {
-            TheRing otherRing = segmentMap.get(seg.references);
-            if( otherRing.countNonReferenceSegments() > 1 ) {
-            // we could check for >0, but it is prone to deadlocking
-            seg.swapReference();
-            }
-        }
-        }
-    }
-
-    // initializing source way for each ring
-    for( TheRing ring : rings )
-        ring.putSourceWayFirst();
+    public static void redistributeSegments(List<TheRing> rings) {
+        // build segments map
+        Map<RingSegment, TheRing> segmentMap = new HashMap<>();
+        for (TheRing ring : rings ) {
+            for (RingSegment seg : ring.segments )
+                if (!seg.isReference() ) {
+                    segmentMap.put(seg, ring);
+                }
+        }
+
+        // rearrange references
+        for (int i = 0; i < rings.size(); i++) {
+            TheRing ring = rings.get(i);
+            if (ring.countNonReferenceSegments() == 0) {
+                // need to find one non-reference segment
+                for (RingSegment seg : ring.segments) {
+                    TheRing otherRing = segmentMap.get(seg.references);
+                    if (otherRing.countNonReferenceSegments() > 1) {
+                        // we could check for >0, but it is prone to deadlocking
+                        seg.swapReference();
+                    }
+                }
+            }
+        }
+
+        // initializing source way for each ring
+        for (TheRing ring : rings ) {
+            ring.putSourceWayFirst();
+        }
     }
 
     private int countNonReferenceSegments() {
-    int count = 0;
-    for( RingSegment seg : segments )
-        if( !seg.isReference() )
-        count++;
-    return count;
+        int count = 0;
+        for (RingSegment seg : segments )
+            if (!seg.isReference() ) {
+                count++;
+            }
+        return count;
     }
 
     public void putSourceWayFirst() {
-    for( RingSegment seg : segments ) {
-        if( !seg.isReference() ) {
-        seg.overrideWay(source);
-        return;
-        }
-    }
-    }
-    
+        for (RingSegment seg : segments) {
+            if (!seg.isReference()) {
+                seg.overrideWay(source);
+                return;
+            }
+        }
+    }
+
     public List<Command> getCommands() {
-    return getCommands(true, null);
-    }
-    
-    public List<Command> getCommands( Map<Relation, Relation> relationChangeMap ) {
-    return getCommands(true, relationChangeMap);
-    }
-    
+        return getCommands(true, null);
+    }
+
+    public List<Command> getCommands(Map<Relation, Relation> relationChangeMap) {
+        return getCommands(true, relationChangeMap);
+    }
+
     /**
      * Returns a list of commands to make a new relation and all newly created ways.
      * The first way is copied from the source one, ChangeCommand is issued in this case.
      */
-    public List<Command> getCommands( boolean createMultipolygon, Map<Relation, Relation> relationChangeMap ) {
-    Way sourceCopy = new Way(source);
-    if( createMultipolygon ) {
-        Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
-        relation = new Relation();
-        relation.put("type", "multipolygon");
-        for( String key : sourceCopy.keySet() ) {
-                if( linearTags.contains(key) ) continue;
-                if( key.equals("natural") && sourceCopy.get("natural").equals("coastline") ) continue;
+    public List<Command> getCommands(boolean createMultipolygon, Map<Relation, Relation> relationChangeMap) {
+        Way sourceCopy = new Way(source);
+        if (createMultipolygon) {
+            Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
+            relation = new Relation();
+            relation.put("type", "multipolygon");
+            for (String key : sourceCopy.keySet()) {
+                if (linearTags.contains(key) ) {
+                    continue;
+                }
+                if (key.equals("natural") && sourceCopy.get("natural").equals("coastline") ) {
+                    continue;
+                }
                 relation.put(key, sourceCopy.get(key));
                 sourceCopy.remove(key);
-        }
-    }
-
-    // build a map of referencing relations
-    Map<Relation, Integer> referencingRelations = new HashMap<>();
-    List<Command> relationCommands = new ArrayList<>();
-    for( OsmPrimitive p : source.getReferrers() ) {
-        if( p instanceof Relation ) {
-        Relation rel = null;
-        if( relationChangeMap != null ) {
-            if( relationChangeMap.containsKey((Relation)p) )
-            rel = relationChangeMap.get((Relation)p);
-            else {
-            rel = new Relation((Relation)p);
-            relationChangeMap.put((Relation)p, rel);
-            }
-        } else {            
-            rel = new Relation((Relation)p);
-            relationCommands.add(new ChangeCommand((Relation)p, rel));
-        }
-        for( int i = 0; i < rel.getMembersCount(); i++ )
-            if( rel.getMember(i).getMember().equals(source) )
-            referencingRelations.put(rel, Integer.valueOf(i));
-        }
-    }
-    // todo: ÐºÐ¾Ð³Ð´Ð° Ð´Ð²Ð° ÐºÐ¾Ð»ÑŒÑ†Ð° Ð¼ÐµÐ½Ñ�ÑŽÑ‚ Ð¾Ð´Ð½Ð¾ Ð¸ Ñ‚Ð¾ Ð¶Ðµ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ðµ, Ð² Ñ�Ð¿Ð¸Ñ�Ð¾Ðº ÐºÐ¾Ð¼Ð°Ð½Ð´ Ð´Ð¾Ð±Ð°Ð²Ð»Ñ�ÐµÑ‚Ñ�Ñ�
-    // Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð³Ð¾ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ� Ð½Ð° Ð½Ð¾Ð²Ð¾Ðµ, Ð° Ð½Ðµ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰ÐµÐ³Ð¾
-    // Ð¿Ð¾Ñ�Ñ‚Ð¾Ð¼Ñƒ Ñ�Ð¾Ñ…Ñ€Ð°Ð½Ñ�ÐµÑ‚Ñ�Ñ� Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð¿ÐµÑ€Ð²Ð¾Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ
-
-    List<Command> commands = new ArrayList<>();
-    boolean foundOwnWay = false;
-    for( RingSegment seg : segments ) {
-        boolean needAdding = !seg.isWayConstructed();
-        Way w = seg.constructWay(seg.isReference() ? null : sourceCopy);
-        if( needAdding )
-        commands.add(new AddCommand(w));
-        if( w.equals(source) ) {
-        if( createMultipolygon || !seg.getWayNodes().equals(source.getNodes()) ) {
-            sourceCopy.setNodes(seg.getWayNodes());
-            commands.add(new ChangeCommand(source, sourceCopy));
-        }
-        foundOwnWay = true;
-        } else {
-        for( Relation rel : referencingRelations.keySet() ) {
-            int relIndex = referencingRelations.get(rel);
-            rel.addMember(new RelationMember(rel.getMember(relIndex).getRole(), w));
-        }
-        }
-        if( createMultipolygon )
-        relation.addMember(new RelationMember("outer", w));
-    }
-    if( !foundOwnWay )
-        commands.add(new DeleteCommand(source));
-    commands.addAll(relationCommands);
-    if( createMultipolygon )
-        commands.add(new AddCommand(relation));
-    return commands;
-    }
-    
-    public static void updateCommandsWithRelations( List<Command> commands, Map<Relation, Relation> relationCache ) {
-    for( Relation src : relationCache.keySet() )
-        commands.add(new ChangeCommand(src, relationCache.get(src)));
+            }
+        }
+
+        // build a map of referencing relations
+        Map<Relation, Integer> referencingRelations = new HashMap<>();
+        List<Command> relationCommands = new ArrayList<>();
+        for (OsmPrimitive p : source.getReferrers()) {
+            if (p instanceof Relation) {
+                Relation rel = null;
+                if (relationChangeMap != null) {
+                    if (relationChangeMap.containsKey(p) ) {
+                        rel = relationChangeMap.get(p);
+                    } else {
+                        rel = new Relation((Relation)p);
+                        relationChangeMap.put((Relation)p, rel);
+                    }
+                } else {
+                    rel = new Relation((Relation)p);
+                    relationCommands.add(new ChangeCommand(p, rel));
+                }
+                for (int i = 0; i < rel.getMembersCount(); i++ )
+                    if (rel.getMember(i).getMember().equals(source) ) {
+                        referencingRelations.put(rel, Integer.valueOf(i));
+                    }
+            }
+        }
+        // todo: ÐºÐ¾Ð³Ð´Ð° Ð´Ð²Ð° ÐºÐ¾Ð»ÑŒÑ†Ð° Ð¼ÐµÐ½Ñ�ÑŽÑ‚ Ð¾Ð´Ð½Ð¾ Ð¸ Ñ‚Ð¾ Ð¶Ðµ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ðµ, Ð² Ñ�Ð¿Ð¸Ñ�Ð¾Ðº ÐºÐ¾Ð¼Ð°Ð½Ð´ Ð´Ð¾Ð±Ð°Ð²Ð»Ñ�ÐµÑ‚Ñ�Ñ�
+        // Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð³Ð¾ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ� Ð½Ð° Ð½Ð¾Ð²Ð¾Ðµ, Ð° Ð½Ðµ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰ÐµÐ³Ð¾
+        // Ð¿Ð¾Ñ�Ñ‚Ð¾Ð¼Ñƒ Ñ�Ð¾Ñ…Ñ€Ð°Ð½Ñ�ÐµÑ‚Ñ�Ñ� Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð¿ÐµÑ€Ð²Ð¾Ðµ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ
+
+        List<Command> commands = new ArrayList<>();
+        boolean foundOwnWay = false;
+        for (RingSegment seg : segments) {
+            boolean needAdding = !seg.isWayConstructed();
+            Way w = seg.constructWay(seg.isReference() ? null : sourceCopy);
+            if (needAdding ) {
+                commands.add(new AddCommand(w));
+            }
+            if (w.equals(source)) {
+                if (createMultipolygon || !seg.getWayNodes().equals(source.getNodes())) {
+                    sourceCopy.setNodes(seg.getWayNodes());
+                    commands.add(new ChangeCommand(source, sourceCopy));
+                }
+                foundOwnWay = true;
+            } else {
+                for (Relation rel : referencingRelations.keySet()) {
+                    int relIndex = referencingRelations.get(rel);
+                    rel.addMember(new RelationMember(rel.getMember(relIndex).getRole(), w));
+                }
+            }
+            if (createMultipolygon ) {
+                relation.addMember(new RelationMember("outer", w));
+            }
+        }
+        if (!foundOwnWay ) {
+            commands.add(new DeleteCommand(source));
+        }
+        commands.addAll(relationCommands);
+        if (createMultipolygon ) {
+            commands.add(new AddCommand(relation));
+        }
+        return commands;
+    }
+
+    public static void updateCommandsWithRelations(List<Command> commands, Map<Relation, Relation> relationCache) {
+        for (Relation src : relationCache.keySet() ) {
+            commands.add(new ChangeCommand(src, relationCache.get(src)));
+        }
     }
 
@@ -381,19 +407,20 @@
      */
     public Relation getRelation() {
-    return relation;
+        return relation;
     }
 
     @Override
     public String toString() {
-    StringBuilder sb = new StringBuilder("TheRing@");
-    sb.append(this.hashCode()).append('[').append("wayId: ").append(source == null ? "null" : source.getUniqueId()).append("; segments: ");
-    if( segments.isEmpty() )
-        sb.append("empty");
-    else {
-        sb.append(segments.get(0));
-        for( int i = 1; i < segments.size(); i++ )
-        sb.append(", ").append(segments.get(i));
-    }
-    return sb.append(']').toString();
+        StringBuilder sb = new StringBuilder("TheRing@");
+        sb.append(this.hashCode()).append('[').append("wayId: ").append(source == null ? "null" : source.getUniqueId()).append("; segments: ");
+        if (segments.isEmpty() ) {
+            sb.append("empty");
+        } else {
+            sb.append(segments.get(0));
+            for (int i = 1; i < segments.size(); i++ ) {
+                sb.append(", ").append(segments.get(i));
+            }
+        }
+        return sb.append(']').toString();
     }
 
@@ -401,6 +428,6 @@
      * Appends "append" to "base" so the closed polygon forms.
      */
-    /*private static void closePolygon( List<Node> base, List<Node> append ) {
-    if( append.get(0).equals(base.get(0)) && append.get(append.size() - 1).equals(base.get(base.size() - 1)) ) {
+    /*private static void closePolygon(List<Node> base, List<Node> append) {
+    if (append.get(0).equals(base.get(0)) && append.get(append.size() - 1).equals(base.get(base.size() - 1))) {
         List<Node> ap2 = new ArrayList<Node>(append);
         Collections.reverse(ap2);
@@ -414,5 +441,5 @@
      * Checks if a middle point between two nodes is inside a polygon. Useful to check if the way is inside.
      */
-    /*private static boolean segmentInsidePolygon( Node n1, Node n2, List<Node> polygon ) {
+    /*private static boolean segmentInsidePolygon(Node n1, Node n2, List<Node> polygon) {
     EastNorth en1 = n1.getEastNorth();
     EastNorth en2 = n2.getEastNorth();
@@ -420,176 +447,182 @@
     return Geometry.nodeInsidePolygon(testNode, polygon);
     }*/
-    
-    private static void log( String s ) {
-//    System.out.println(s);
-    }
-    
+
+    private static void log(String s) {
+        //    System.out.println(s);
+    }
+
     private static class RingSegment {
-    private List<Node> nodes;
-    private RingSegment references;
-    private Way resultingWay = null;
-    private boolean wasTemplateApplied = false;
-    private boolean isRing;
-
-    /*private RingSegment() {
+        private List<Node> nodes;
+        private RingSegment references;
+        private Way resultingWay = null;
+        private boolean wasTemplateApplied = false;
+        private boolean isRing;
+
+        /*private RingSegment() {
     }*/
 
-    public RingSegment( Way w ) {
-        this(w.getNodes());
-    }
-
-    public RingSegment( List<Node> nodes ) {
-        this.nodes = nodes;
-        isRing = nodes.size() > 1 && nodes.get(0).equals(nodes.get(nodes.size() - 1));
-        if( isRing )
-        nodes.remove(nodes.size() - 1);
-        references = null;
-    }
-
-    /*public RingSegment( RingSegment ref ) {
+        public RingSegment(Way w) {
+            this(w.getNodes());
+        }
+
+        public RingSegment(List<Node> nodes) {
+            this.nodes = nodes;
+            isRing = nodes.size() > 1 && nodes.get(0).equals(nodes.get(nodes.size() - 1));
+            if (isRing ) {
+                nodes.remove(nodes.size() - 1);
+            }
+            references = null;
+        }
+
+        /*public RingSegment(RingSegment ref) {
         this.nodes = null;
         this.references = ref;
     }*/
 
-    /**
-     * Splits this segment at node n. Retains nodes 0..n and moves
-     * nodes n..N to a separate segment that is returned.
-     * @param n node at which to split.
-     * @return new segment, {@code null} if splitting is unnecessary.
-     */
-    public RingSegment split( Node n ) {
-        if( nodes == null )
-        throw new IllegalArgumentException("Cannot split segment: it is a reference");
-        int pos = nodes.indexOf(n);
-        if( pos <= 0 || pos >= nodes.size() - 1 )
-        return null;
-        List<Node> newNodes = new ArrayList<>(nodes.subList(pos, nodes.size()));
-        nodes.subList(pos + 1, nodes.size()).clear();
-        return new RingSegment(newNodes);
-    }
-
-    /**
-     * Split this segment as a way at two nodes. If one of them is null or at the end,
-     * split as an arc. Note: order of nodes is important.
-     * @return A new segment from n2 to n1.
-     */
-    public RingSegment split( Node n1, Node n2 ) {
-        if( nodes == null )
-        throw new IllegalArgumentException("Cannot split segment: it is a reference");
-        if( !isRing ) {
-        if( n1 == null || nodes.get(0).equals(n1) || nodes.get(nodes.size() - 1).equals(n1) )
-            return split(n2);
-        if( n2 == null || nodes.get(0).equals(n2) || nodes.get(nodes.size() - 1).equals(n2) )
-            return split(n1);
-        throw new IllegalArgumentException("Split for two nodes is called for not-ring: " + this);
-        }
-        int pos1 = nodes.indexOf(n1);
-        int pos2 = nodes.indexOf(n2);
-        if( pos1 == pos2 )
-        return null;
-
-        List<Node> newNodes = new ArrayList<>();
-        if( pos2 > pos1 ) {
-        newNodes.addAll(nodes.subList(pos2, nodes.size()));
-        newNodes.addAll(nodes.subList(0, pos1 + 1));
-        if( pos2 + 1 < nodes.size() )
-            nodes.subList(pos2 + 1, nodes.size()).clear();
-        if( pos1 > 0 )
-            nodes.subList(0, pos1).clear();
-        } else {
-        newNodes.addAll(nodes.subList(pos2, pos1 + 1));
-        nodes.addAll(new ArrayList<>(nodes.subList(0, pos2 + 1)));
-        nodes.subList(0, pos1).clear();
-        }
-        isRing = false;
-        return new RingSegment(newNodes);
-    }
-
-    public List<Node> getNodes() {
-        return nodes == null ? references.nodes : nodes;
-    }
-
-    public List<Node> getWayNodes() {
-        if( nodes == null )
-        throw new IllegalArgumentException("Won't give you wayNodes: it is a reference");
-        List<Node> wayNodes = new ArrayList<>(nodes);
-        if( isRing )
-        wayNodes.add(wayNodes.get(0));
-        return wayNodes;
-    }
-
-    public boolean isReference() {
-        return nodes == null;
-    }
-
-    public boolean isRing() {
-        return isRing;
-    }
-
-    public void makeReference( RingSegment segment ) {
-        log(this + " was made a reference to " + segment);
-        this.nodes = null;
-        this.references = segment;
-    }
-
-    public void swapReference() {
-        this.nodes = references.nodes;
-        references.nodes = null;
-        references.references = this;
-        this.references = null;
-    }
-
-    public boolean isWayConstructed() {
-        return isReference() ? references.isWayConstructed() : resultingWay != null;
-    }
-
-    public Way constructWay( Way template ) {
-        if( isReference() )
-        return references.constructWay(template);
-        if( resultingWay == null ) {
-        resultingWay = new Way();
-        resultingWay.setNodes(getWayNodes());
-        }
-        if( template != null && !wasTemplateApplied ) {
-        resultingWay.setKeys(template.getKeys());
-        wasTemplateApplied = true;
-        }
-        return resultingWay;
-    }
-
-    public void overrideWay( Way source ) {
-        if( isReference() )
-        references.overrideWay(source);
-        else {
-        resultingWay = source;
-        wasTemplateApplied = true;
-        }
-    }
-
-    /**
-     * Compares two segments with respect to referencing.
-     * @return true if ways are equals, or one references another.
-     */
-    /*public boolean isReferencingEqual( RingSegment other ) {
+        /**
+         * Splits this segment at node n. Retains nodes 0..n and moves
+         * nodes n..N to a separate segment that is returned.
+         * @param n node at which to split.
+         * @return new segment, {@code null} if splitting is unnecessary.
+         */
+        public RingSegment split(Node n) {
+            if (nodes == null )
+                throw new IllegalArgumentException("Cannot split segment: it is a reference");
+            int pos = nodes.indexOf(n);
+            if (pos <= 0 || pos >= nodes.size() - 1 )
+                return null;
+            List<Node> newNodes = new ArrayList<>(nodes.subList(pos, nodes.size()));
+            nodes.subList(pos + 1, nodes.size()).clear();
+            return new RingSegment(newNodes);
+        }
+
+        /**
+         * Split this segment as a way at two nodes. If one of them is null or at the end,
+         * split as an arc. Note: order of nodes is important.
+         * @return A new segment from n2 to n1.
+         */
+        public RingSegment split(Node n1, Node n2) {
+            if (nodes == null )
+                throw new IllegalArgumentException("Cannot split segment: it is a reference");
+            if (!isRing) {
+                if (n1 == null || nodes.get(0).equals(n1) || nodes.get(nodes.size() - 1).equals(n1) )
+                    return split(n2);
+                if (n2 == null || nodes.get(0).equals(n2) || nodes.get(nodes.size() - 1).equals(n2) )
+                    return split(n1);
+                throw new IllegalArgumentException("Split for two nodes is called for not-ring: " + this);
+            }
+            int pos1 = nodes.indexOf(n1);
+            int pos2 = nodes.indexOf(n2);
+            if (pos1 == pos2 )
+                return null;
+
+            List<Node> newNodes = new ArrayList<>();
+            if (pos2 > pos1) {
+                newNodes.addAll(nodes.subList(pos2, nodes.size()));
+                newNodes.addAll(nodes.subList(0, pos1 + 1));
+                if (pos2 + 1 < nodes.size() ) {
+                    nodes.subList(pos2 + 1, nodes.size()).clear();
+                }
+                if (pos1 > 0 ) {
+                    nodes.subList(0, pos1).clear();
+                }
+            } else {
+                newNodes.addAll(nodes.subList(pos2, pos1 + 1));
+                nodes.addAll(new ArrayList<>(nodes.subList(0, pos2 + 1)));
+                nodes.subList(0, pos1).clear();
+            }
+            isRing = false;
+            return new RingSegment(newNodes);
+        }
+
+        public List<Node> getNodes() {
+            return nodes == null ? references.nodes : nodes;
+        }
+
+        public List<Node> getWayNodes() {
+            if (nodes == null )
+                throw new IllegalArgumentException("Won't give you wayNodes: it is a reference");
+            List<Node> wayNodes = new ArrayList<>(nodes);
+            if (isRing ) {
+                wayNodes.add(wayNodes.get(0));
+            }
+            return wayNodes;
+        }
+
+        public boolean isReference() {
+            return nodes == null;
+        }
+
+        public boolean isRing() {
+            return isRing;
+        }
+
+        public void makeReference(RingSegment segment) {
+            log(this + " was made a reference to " + segment);
+            this.nodes = null;
+            this.references = segment;
+        }
+
+        public void swapReference() {
+            this.nodes = references.nodes;
+            references.nodes = null;
+            references.references = this;
+            this.references = null;
+        }
+
+        public boolean isWayConstructed() {
+            return isReference() ? references.isWayConstructed() : resultingWay != null;
+        }
+
+        public Way constructWay(Way template) {
+            if (isReference() )
+                return references.constructWay(template);
+            if (resultingWay == null) {
+                resultingWay = new Way();
+                resultingWay.setNodes(getWayNodes());
+            }
+            if (template != null && !wasTemplateApplied) {
+                resultingWay.setKeys(template.getKeys());
+                wasTemplateApplied = true;
+            }
+            return resultingWay;
+        }
+
+        public void overrideWay(Way source) {
+            if (isReference() ) {
+                references.overrideWay(source);
+            } else {
+                resultingWay = source;
+                wasTemplateApplied = true;
+            }
+        }
+
+        /**
+         * Compares two segments with respect to referencing.
+         * @return true if ways are equals, or one references another.
+         */
+        /*public boolean isReferencingEqual(RingSegment other) {
         return this.equals(other) || (other.isReference() && other.references == this) || (isReference() && references == other);
     }*/
 
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("RingSegment@");
-        sb.append(this.hashCode()).append('[');
-        if( isReference() )
-        sb.append("references ").append(references.hashCode());
-        else if( nodes.isEmpty() )
-        sb.append("empty");
-        else {
-        if( isRing )
-            sb.append("ring:");
-        sb.append(nodes.get(0).getUniqueId());
-        for( int i = 1; i < nodes.size(); i++ )
-            sb.append(',').append(nodes.get(i).getUniqueId());
-        }
-        return sb.append(']').toString();
-    }
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder("RingSegment@");
+            sb.append(this.hashCode()).append('[');
+            if (isReference() ) {
+                sb.append("references ").append(references.hashCode());
+            } else if (nodes.isEmpty() ) {
+                sb.append("empty");
+            } else {
+                if (isRing ) {
+                    sb.append("ring:");
+                }
+                sb.append(nodes.get(0).getUniqueId());
+                for (int i = 1; i < nodes.size(); i++ ) {
+                    sb.append(',').append(nodes.get(i).getUniqueId());
+                }
+            }
+            return sb.append(']').toString();
+        }
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/AssociatedStreetFixer.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/AssociatedStreetFixer.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/AssociatedStreetFixer.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.relationfix;
 
@@ -46,5 +47,7 @@
         // check that all street members have same name as relation (???)
         String streetName = rel.get("name");
-        if (streetName == null) streetName = "";
+        if (streetName == null) {
+            streetName = "";
+        }
         for (RelationMember m : rel.getMembers()) {
             if ("street".equals(m.getRole()) && !streetName.equals(m.getWay().get("name"))) {
@@ -101,13 +104,16 @@
         // fill relation name
         Map<String, Integer> streetNames = new HashMap<>();
-        for (RelationMember m : rel.getMembers())
+        for (RelationMember m : rel.getMembers()) {
             if ("street".equals(m.getRole()) && m.isWay()) {
                 String name = m.getWay().get("name");
-                if (name == null || name.isEmpty()) continue;
+                if (name == null || name.isEmpty()) {
+                    continue;
+                }
 
                 Integer count = streetNames.get(name);
 
-                streetNames.put(name, count != null? count + 1 : 1);
+                streetNames.put(name, count != null ? count + 1 : 1);
             }
+        }
         String commonName = "";
         Integer commonCount = 0;
@@ -146,5 +152,5 @@
                 commandList.add(new ChangeCommand(oldWay, newWay));
             }
-        */
+         */
         // return results
         if (commandList.size() == 0)
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/BoundaryFixer.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/BoundaryFixer.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/BoundaryFixer.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.relationfix;
 
@@ -32,5 +33,5 @@
     @Override
     public boolean isRelationGood(Relation rel) {
-        for( RelationMember m : rel.getMembers() ) {
+        for (RelationMember m : rel.getMembers()) {
             if (m.getType().equals(OsmPrimitiveType.RELATION) && !"subarea".equals(m.getRole())) {
                 setWarningMessage(tr("Relation without ''subarea'' role found"));
@@ -67,16 +68,16 @@
     }
 
-    private Relation fixBoundaryRoles( Relation source ) {
+    private Relation fixBoundaryRoles(Relation source) {
         Relation r = new Relation(source);
         boolean fixed = false;
-        for( int i = 0; i < r.getMembersCount(); i++ ) {
+        for (int i = 0; i < r.getMembersCount(); i++) {
             RelationMember m = r.getMember(i);
             String role = null;
-            if( m.isRelation() )
+            if (m.isRelation()) {
                 role = "subarea";
-            else if( m.isNode() ) {
-                Node n = (Node)m.getMember();
-                if( !n.isIncomplete() ) {
-                    if( n.hasKey("place") ) {
+            } else if (m.isNode()) {
+                Node n = (Node) m.getMember();
+                if (!n.isIncomplete()) {
+                    if (n.hasKey("place")) {
                         String place = n.get("place");
                         if (place.equals("state") || place.equals("country") ||
@@ -86,9 +87,10 @@
                             role = "admin_centre";
                         }
-                    } else
+                    } else {
                         role = "label";
+                    }
                 }
             }
-            if( role != null && !role.equals(m.getRole()) ) {
+            if (role != null && !role.equals(m.getRole())) {
                 r.setMember(i, new RelationMember(role, m.getMember()));
                 fixed = true;
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/MultipolygonFixer.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/MultipolygonFixer.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/MultipolygonFixer.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.relationfix;
 
@@ -30,12 +31,12 @@
     }
 
-
     @Override
     public boolean isRelationGood(Relation rel) {
-        for (RelationMember m : rel.getMembers())
+        for (RelationMember m : rel.getMembers()) {
             if (m.getType().equals(OsmPrimitiveType.WAY) && !("outer".equals(m.getRole()) || "inner".equals(m.getRole()))) {
                 setWarningMessage(tr("Way without ''inner'' or ''outer'' role found"));
                 return false;
             }
+        }
         clearWarningMessage();
         return true;
@@ -45,5 +46,5 @@
     public Command fixRelation(Relation rel) {
         Relation rr = fixMultipolygonRoles(rel);
-        return rr != null? new ChangeCommand(rel, rr) : null;
+        return rr != null ? new ChangeCommand(rel, rr) : null;
     }
 
@@ -51,12 +52,14 @@
      * Basically, created multipolygon from scratch, and if successful, replace roles with new ones.
      */
-    protected Relation fixMultipolygonRoles( Relation source ) {
+    protected Relation fixMultipolygonRoles(Relation source) {
         Collection<Way> ways = new ArrayList<>();
-        for( OsmPrimitive p : source.getMemberPrimitives() )
-            if( p instanceof Way )
-                ways.add((Way)p);
+        for (OsmPrimitive p : source.getMemberPrimitives()) {
+            if (p instanceof Way) {
+                ways.add((Way) p);
+            }
+        }
         MultipolygonBuilder mpc = new MultipolygonBuilder();
         String error = mpc.makeFromWays(ways);
-        if( error != null )
+        if (error != null)
             return null;
 
@@ -64,20 +67,25 @@
         boolean fixed = false;
         Set<Way> outerWays = new HashSet<>();
-        for( MultipolygonBuilder.JoinedPolygon poly : mpc.outerWays )
-            for( Way w : poly.ways )
+        for (MultipolygonBuilder.JoinedPolygon poly : mpc.outerWays) {
+            for (Way w : poly.ways) {
                 outerWays.add(w);
+            }
+        }
         Set<Way> innerWays = new HashSet<>();
-        for( MultipolygonBuilder.JoinedPolygon poly : mpc.innerWays )
-            for( Way w : poly.ways )
+        for (MultipolygonBuilder.JoinedPolygon poly : mpc.innerWays) {
+            for (Way w : poly.ways) {
                 innerWays.add(w);
-        for( int i = 0; i < r.getMembersCount(); i++ ) {
+            }
+        }
+        for (int i = 0; i < r.getMembersCount(); i++) {
             RelationMember m = r.getMember(i);
-            if( m.isWay() ) {
+            if (m.isWay()) {
                 String role = null;
-                if( outerWays.contains((Way)m.getMember()) )
+                if (outerWays.contains(m.getMember())) {
                     role = "outer";
-                else if( innerWays.contains((Way)m.getMember()) )
+                } else if (innerWays.contains(m.getMember())) {
                     role = "inner";
-                if( role != null && !role.equals(m.getRole()) ) {
+                }
+                if (role != null && !role.equals(m.getRole())) {
                     r.setMember(i, new RelationMember(role, m.getMember()));
                     fixed = true;
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/NothingFixer.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/NothingFixer.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/NothingFixer.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.relationfix;
 
@@ -12,8 +13,10 @@
         super("");
     }
+
     @Override
     public boolean isFixerApplicable(Relation rel) {
         return true;
     }
+
     @Override
     public boolean isRelationGood(Relation rel) {
@@ -25,4 +28,3 @@
         return null;
     }
-
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/PublicTransportFixer.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/PublicTransportFixer.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/PublicTransportFixer.java	(revision 32395)
@@ -1,3 +1,6 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.relationfix;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -6,5 +9,5 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
-import static org.openstreetmap.josm.tools.I18n.tr;
+
 import relcontext.actions.PublicTransportHelper;
 
@@ -18,5 +21,5 @@
  */
 public class PublicTransportFixer extends RelationFixer {
-    	
+
     public PublicTransportFixer() {
         super("route", "public_transport");
@@ -30,5 +33,5 @@
     public boolean isRelationGood(Relation rel) {
         for (RelationMember m : rel.getMembers()) {
-            if (m.getType().equals(OsmPrimitiveType.NODE) 
+            if (m.getType().equals(OsmPrimitiveType.NODE)
                     && !(m.getRole().startsWith(PublicTransportHelper.STOP) || m.getRole().startsWith(PublicTransportHelper.PLATFORM))) {
                 setWarningMessage(tr("Node without ''stop'' or ''platform'' role found"));
@@ -62,9 +65,9 @@
         return fixed ? new ChangeCommand(rel, r) : null;
     }
-    
+
     private Relation fixStopPlatformRole(Relation source) {
         Relation r = new Relation(source);
         boolean fixed = false;
-        for( int i = 0; i < r.getMembersCount(); i++ ) {
+        for (int i = 0; i < r.getMembersCount(); i++) {
             RelationMember m = r.getMember(i);
             String role = PublicTransportHelper.getRoleByMember(m);
@@ -75,5 +78,5 @@
             }
         }
-        return fixed ? r : null;            
+        return fixed ? r : null;
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/RelationFixer.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/RelationFixer.java	(revision 32394)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/RelationFixer.java	(revision 32395)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package relcontext.relationfix;
 
@@ -20,9 +21,9 @@
     /**
      * Construct new RelationFixer by a list of applicable types
-     * @param types
+     * @param types types
      */
     public RelationFixer(String... types) {
         applicableTypes = new ArrayList<>();
-        for(String type: types) {
+        for (String type: types) {
             applicableTypes.add(type);
         }
@@ -33,5 +34,5 @@
      * and then check desired relation properties.
      * Note that this only verifies if current RelationFixer can be used to check and fix given relation
-     * Deeper relation checking is at {@link isRelationGood}
+     * Deeper relation checking is at {@link #isRelationGood}
      *
      * @param rel Relation to check
@@ -45,7 +46,8 @@
 
         String type = rel.get("type");
-        for(String oktype: applicableTypes)
+        for (String oktype: applicableTypes) {
             if (oktype.equals(type))
                 return true;
+        }
 
         return false;
@@ -73,4 +75,5 @@
         this.sortAndFixAction = sortAndFixAction;
     }
+
     protected void setWarningMessage(String text) {
         if (text == null) {
@@ -80,7 +83,7 @@
         }
     }
+
     protected void clearWarningMessage() {
         sortAndFixAction.putValue(Action.SHORT_DESCRIPTION, tr("Fix roles of the chosen relation members"));
     }
-
 }
