Index: /applications/editors/josm/plugins/relcontext/TODO
===================================================================
--- /applications/editors/josm/plugins/relcontext/TODO	(revision 25691)
+++ /applications/editors/josm/plugins/relcontext/TODO	(revision 25692)
@@ -1,10 +1,6 @@
-- Create plugin icon
-- Store all settings in preferences
-- Fix everything to work with multiple [editor] layers
-- Create multipolygon settings button ">"
 - After creating multipolygon, move tags from outer to relation (setting "tags")
-- Choose whether creating multipoly or administrative boundary
 - Solve width problem for narrows buttons when "fix" and "download" appear simultaneously
 - Check all strings to be properly formulated, search for similar ones in josm core and plugins
+- Draw icons for multipoly settings menu
 
 == BETA ==
@@ -17,4 +13,5 @@
 - Break touching rings of multipolygons
 - Option to create separate multipolygon for every outer ring
+- Solve multipolygon settings button width problem
 
 == RELEASE ==
Index: /applications/editors/josm/plugins/relcontext/build.xml
===================================================================
--- /applications/editors/josm/plugins/relcontext/build.xml	(revision 25691)
+++ /applications/editors/josm/plugins/relcontext/build.xml	(revision 25692)
@@ -79,4 +79,7 @@
         <copy todir="${plugin.build.dir}/images">
             <fileset dir="images"/>
+        </copy>
+        <copy todir="${plugin.build.dir}">
+            <fileset dir="src" includes="**/*.txt" />
         </copy>
         <copy todir="${plugin.build.dir}">
Index: /applications/editors/josm/plugins/relcontext/src/relcontext/ChosenRelation.java
===================================================================
--- /applications/editors/josm/plugins/relcontext/src/relcontext/ChosenRelation.java	(revision 25691)
+++ /applications/editors/josm/plugins/relcontext/src/relcontext/ChosenRelation.java	(revision 25692)
@@ -88,7 +88,8 @@
         // todo: dim chosen relation when changing layer
         // todo: check this WTF!
-        if( newLayer != null ) {
+        clear();
+        if( newLayer != null && oldLayer == null ) {
             Main.map.mapView.addTemporaryLayer(this);
-        } else {
+        } else if( oldLayer != null ) {
             Main.map.mapView.removeTemporaryLayer(this);
         }
Index: /applications/editors/josm/plugins/relcontext/src/relcontext/RelContextDialog.java
===================================================================
--- /applications/editors/josm/plugins/relcontext/src/relcontext/RelContextDialog.java	(revision 25691)
+++ /applications/editors/josm/plugins/relcontext/src/relcontext/RelContextDialog.java	(revision 25692)
@@ -1,4 +1,10 @@
 package relcontext;
 
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.InputStreamReader;
+import java.awt.Point;
 import java.awt.Component;
 import java.awt.Dimension;
@@ -50,8 +56,12 @@
 public class RelContextDialog extends ToggleDialog implements EditLayerChangeListener, ChosenRelationListener, SelectionChangedListener {
 
+    public final static String PREF_PREFIX = "reltoolbox";
+    private static final String PREF_ROLEBOX = PREF_PREFIX + ".rolebox";
+
     private final DefaultTableModel relationsData;
     private ChosenRelation chosenRelation;
     private JPanel chosenRelationPanel;
     private ChosenRelationPopupMenu popupMenu;
+    private MultipolygonSettingsPopup multiPopupMenu;
     private JLabel crRoleIndicator;
     private AutoCompletingComboBox roleBox;
@@ -59,14 +69,17 @@
 
     public RelContextDialog() {
-        super(tr("Relation Toolbox"), "reltoolbox",
+        super(tr("Relation Toolbox"), PREF_PREFIX,
                 tr("Open relation/multipolygon editor panel"),
                 Shortcut.registerShortcut("subwindow:reltoolbox", tr("Toggle: {0}", tr("Relation Toolbox")),
                 KeyEvent.VK_R, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 150, true);
 
-        JPanel rcPanel = new JPanel(new BorderLayout());
-
         chosenRelation = new ChosenRelation();
         chosenRelation.addChosenRelationListener(this);
         MapView.addEditLayerChangeListener(chosenRelation);
+
+        popupMenu = new ChosenRelationPopupMenu();
+        multiPopupMenu = new MultipolygonSettingsPopup();
+
+        JPanel rcPanel = new JPanel(new BorderLayout());
 
         relationsData = new RelationTableModel();
@@ -127,4 +140,5 @@
             @Override
             public void componentHidden( ComponentEvent e ) {
+                Main.pref.put(PREF_ROLEBOX + ".visible", false);
                 toggleRolePanelButtonTop.setVisible(true);
             }
@@ -132,8 +146,11 @@
             @Override
             public void componentShown( ComponentEvent e ) {
+                Main.pref.put(PREF_ROLEBOX + ".visible", true);
                 toggleRolePanelButtonTop.setVisible(false);
             }
         });
+        rolePanel.setVisible(Main.pref.getBoolean(PREF_ROLEBOX + ".visible", true));
         toggleRolePanelButtonTop.setVisible(!rolePanel.isVisible());
+        lastSelectedRole = Main.pref.get(PREF_ROLEBOX + ".lastrole");
 
         sortAndFixAction.addPropertyChangeListener(new PropertyChangeListener() {
@@ -155,12 +172,29 @@
         JPanel bottomLine = new JPanel(new GridBagLayout());
         bottomLine.add(new JButton(new CreateRelationAction(chosenRelation)), GBC.std());
-        bottomLine.add(new JButton(new CreateMultipolygonAction(chosenRelation)), GBC.std());
+        final JButton multipolygonButton = new JButton(new CreateMultipolygonAction(chosenRelation));
+        bottomLine.add(multipolygonButton, GBC.std());
+//        bottomLine.add(sizeButton(new JButton(new MultipolygonSettingsAction()), 16, 0), GBC.std().fill(GBC.VERTICAL));
         bottomLine.add(Box.createHorizontalGlue(), GBC.std().fill());
         bottomLine.add(new JButton(new FindRelationAction(chosenRelation)), GBC.eol());
         rcPanel.add(sizeButton(bottomLine, 0, 24), BorderLayout.SOUTH);
 
+        multipolygonButton.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed( MouseEvent e ) {
+                checkPopup(e);
+            }
+
+            @Override
+            public void mouseReleased( MouseEvent e ) {
+                checkPopup(e);
+            }
+
+            private void checkPopup( MouseEvent e ) {
+                if( e.isPopupTrigger() )
+                    multiPopupMenu.show(e.getComponent(), e.getX(), e.getY());
+            }
+        });
+
         add(rcPanel, BorderLayout.CENTER);
-
-        popupMenu = new ChosenRelationPopupMenu();
     }
 
@@ -223,4 +257,5 @@
         MapView.removeEditLayerChangeListener(this);
         DatasetEventManager.getInstance().removeDatasetListener(chosenRelation);
+        chosenRelation.clear();
     }
 
@@ -319,17 +354,30 @@
     }
 
-    private static final Map<String, String[]> possibleRoles = new HashMap<String, String[]>();
-    static {
-        possibleRoles.put("boundary", new String[] {"admin_centre", "label", "subarea"});
-        possibleRoles.put("route", new String[] {"forward", "backward", "stop", "platform"});
-        possibleRoles.put("restriction", new String[] {"from", "to", "via", "location_hint"});
-        possibleRoles.put("enforcement", new String[] {"device", "from", "to", "force"});
-        possibleRoles.put("destination_sign", new String[] {"to", "from", "intersection", "sign"});
-        possibleRoles.put("site", new String[] {"perimeter", "entrance", "label"});
-        possibleRoles.put("bridge", new String[] {"across", "under", "outline", "edge"});
-        possibleRoles.put("tunnel", new String[] {"through", "outline", "edge"});
-        possibleRoles.put("surveillance", new String[] {"camera", "extent", "visible", "hidden"});
-        possibleRoles.put("street", new String[] {"street", "address", "house", "associated"});
-        possibleRoles.put("collection", new String[] {"member", "street", "river", "railway", "address", "associated"});
+    private static final String POSSIBLE_ROLES_FILE = "relcontext/possible_roles.txt";
+    private static final Map<String, List<String>> possibleRoles = loadRoles();
+
+    private static Map<String, List<String>> loadRoles() {
+        Map<String, List<String>> result = new HashMap<String, List<String>>();
+        try {
+            ClassLoader classLoader = RelContextDialog.class.getClassLoader();
+            final 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() ) {
+                    String type = t.nextToken();
+                    List<String> roles = new ArrayList<String>();
+                    while( t.hasMoreTokens() )
+                        roles.add(t.nextToken());
+                    result.put(type, roles);
+                }
+            }
+            r.close();
+        } catch( Exception e ) {
+            System.err.println("[RelToolbox] Error reading possible roles file.");
+            e.printStackTrace();
+        }
+        return result;
     }
 
@@ -344,7 +392,7 @@
             }
             if( chosenRelation.get().get("type") != null ) {
-                String[] values = possibleRoles.get(chosenRelation.get().get("type"));
+                List<String> values = possibleRoles.get(chosenRelation.get().get("type"));
                 if( values != null )
-                    items.addAll(Arrays.asList(values));
+                    items.addAll(values);
             }
             for( RelationMember m : chosenRelation.get().getMembers() )
@@ -354,4 +402,5 @@
         if( currentRole != null && currentRole.length() > 1 ) {
             lastSelectedRole = currentRole;
+            Main.pref.put(PREF_ROLEBOX + ".lastrole", lastSelectedRole);
         }
         roleBox.setPossibleItems(items);
@@ -456,4 +505,5 @@
 
         public void actionPerformed( ActionEvent e ) {
+            Main.pref.put(PREF_ROLEBOX + ".visible", !component.isVisible());
             component.setVisible(!component.isVisible());
         }
@@ -521,3 +571,46 @@
         }
     }
+
+    private class MultipolygonSettingsAction extends AbstractAction {
+        public MultipolygonSettingsAction() {
+            super();
+            putValue(SMALL_ICON, ImageProvider.get("svpRight"));
+            putValue(SHORT_DESCRIPTION, tr("Change multipolygon creation settings"));
+        }
+
+        public void actionPerformed( ActionEvent e ) {
+            Component c = e.getSource() instanceof Component ? (Component)e.getSource() : Main.parent;
+            Point p = getMousePosition();
+            multiPopupMenu.show(c, 0, 0);
+        }
+    }
+
+    private class MultipolygonSettingsPopup extends JPopupMenu implements ActionListener {
+        public MultipolygonSettingsPopup() {
+            super();
+            addMenuItem("boundary", "Create administrative boundary relations");
+            addMenuItem("boundaryways", "Add tags boundary and admin_level to boundary relation ways");
+            addMenuItem("tags", "Move area tags from contour to relation").setEnabled(false);
+            addMenuItem("single", "Create a single multipolygon for multiple outer contours").setEnabled(false);
+        }
+
+        protected final JCheckBoxMenuItem addMenuItem( String property, String title ) {
+            String fullProperty = PREF_PREFIX + ".multipolygon." + property;
+            JCheckBoxMenuItem item = new JCheckBoxMenuItem(tr(title));
+            item.setSelected(Main.pref.getBoolean(fullProperty, CreateMultipolygonAction.getDefaultPropertyValue(property)));
+            item.setActionCommand(fullProperty);
+            item.addActionListener(this);
+            add(item);
+            return item;
+        }
+
+        public void actionPerformed( ActionEvent e ) {
+            String property = e.getActionCommand();
+            if( property != null && property.length() > 0 && e.getSource() instanceof JCheckBoxMenuItem ) {
+                boolean value = ((JCheckBoxMenuItem)e.getSource()).isSelected();
+                Main.pref.put(property, value);
+                show(getInvoker(), getX(), getY());
+            }
+        }
+    }
 }
Index: /applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateMultipolygonAction.java
===================================================================
--- /applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateMultipolygonAction.java	(revision 25691)
+++ /applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateMultipolygonAction.java	(revision 25692)
@@ -1,19 +1,16 @@
 package relcontext.actions;
 
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
+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.util.*;
-import javax.swing.JOptionPane;
+import javax.swing.*;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.command.AddCommand;
-import org.openstreetmap.josm.command.ChangePropertyCommand;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.SequenceCommand;
-import org.openstreetmap.josm.data.osm.MultipolygonCreate;
-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.command.*;
+import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.tools.GBC;
 import relcontext.ChosenRelation;
 
@@ -26,4 +23,5 @@
 public class CreateMultipolygonAction extends JosmAction {
     private static final String ACTION_NAME = "Create relation";
+    private static final String PREF_MULTIPOLY = "reltoolbox.multipolygon.";
     protected ChosenRelation chRel;
 
@@ -36,4 +34,16 @@
     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 false;
+        else if( property.equals("single") ) return true;
+        throw new IllegalArgumentException(property);
+    }
+
+    private boolean getPref( String property ) {
+        return Main.pref.getBoolean(PREF_MULTIPOLY + property, getDefaultPropertyValue(property));
     }
 
@@ -47,5 +57,11 @@
         }
         Relation rel = new Relation();
-        rel.put("type", "multipolygon");
+        boolean isBoundary = getPref("boundary");
+        if( isBoundary ) {
+            rel.put("type", "boundary");
+            rel.put("boundary", "administrative");
+            askForAdminLevelAndName(rel);
+        } else
+            rel.put("type", "multipolygon");
         for( MultipolygonCreate.JoinedPolygon poly : mpc.outerWays )
             for( Way w : poly.ways )
@@ -54,5 +70,9 @@
             for( Way w : poly.ways )
                 rel.addMember(new RelationMember("inner", w));
+        if( isBoundary )
+            addBoundaryMembers(rel);
         List<Command> list = removeTagsFromInnerWays(rel);
+        if( isBoundary && getPref("boundaryways") )
+            list.addAll(fixWayTagsForBoundary(rel));
         list.add(new AddCommand(rel));
         Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), list));
@@ -77,11 +97,83 @@
             enabled = false;
         else {
-            for( OsmPrimitive p : selection )
-                if( !(p instanceof Way) ) {
-                    enabled = false;
-                    break;
-                }
+            if( !getPref("boundary") ) {
+                for( OsmPrimitive p : selection ) {
+                    if( !(p instanceof Way) ) {
+                        enabled = false;
+                        break;
+                    }
+                }
+            }
         }
         setEnabled(enabled);
+    }
+
+    /**
+     * 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));
+        }
+    }
+
+    /**
+     * For all untagged ways in relation, add tags boundary and admin_level.
+     */
+    private List<Command> fixWayTagsForBoundary( Relation rel ) {
+        List<Command> commands = new ArrayList<Command>();
+        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<OsmPrimitive>();
+        Set<OsmPrimitive> waysAdminLevel = new HashSet<OsmPrimitive>();
+        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;
     }
 
@@ -137,3 +229,53 @@
         return commands;
     }
+
+    private void askForAdminLevelAndName( Relation rel ) {
+        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(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));
+
+        final JTextField name = new JTextField();
+        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 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;
+        }
+
+        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);
+    }
 }
Index: /applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateRelationAction.java
===================================================================
--- /applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateRelationAction.java	(revision 25691)
+++ /applications/editors/josm/plugins/relcontext/src/relcontext/actions/CreateRelationAction.java	(revision 25692)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import relcontext.ChosenRelation;
+import relcontext.RelContextDialog;
 
 /**
@@ -32,4 +33,5 @@
 public class CreateRelationAction extends JosmAction {
     private static final String ACTION_NAME = "Create relation";
+    private static final String PREF_LASTTYPE = "reltoolbox.createrelation.lasttype";
     protected ChosenRelation chRel;
 
@@ -90,4 +92,5 @@
         keys.setPossibleItems(RELATION_TYPES);
         keys.setEditable(true);
+        keys.getEditor().setItem(Main.pref.get(PREF_LASTTYPE, "multipolygon"));
 
         panel.add(new JLabel(tr("Type")), GBC.std());
@@ -120,5 +123,7 @@
         }
 
-        return keys.getEditor().getItem().toString().trim();
+        String result = keys.getEditor().getItem().toString().trim();
+        Main.pref.put(PREF_LASTTYPE, result);
+        return result;
     }
 }
Index: /applications/editors/josm/plugins/relcontext/src/relcontext/actions/SortAndFixAction.java
===================================================================
--- /applications/editors/josm/plugins/relcontext/src/relcontext/actions/SortAndFixAction.java	(revision 25691)
+++ /applications/editors/josm/plugins/relcontext/src/relcontext/actions/SortAndFixAction.java	(revision 25692)
@@ -116,5 +116,5 @@
         for( int i = 0; i < r.getMembersCount(); i++ ) {
             RelationMember m = r.getMember(i);
-            if( m.getType().equals(OsmPrimitiveType.WAY) ) {
+            if( m.isWay() ) {
                 String role = null;
                 if( outerWays.contains((Way)m.getMember()) )
@@ -137,7 +137,7 @@
             RelationMember m = r.getMember(i);
             String role = null;
-            if( m.getType().equals(OsmPrimitiveType.RELATION) )
+            if( m.isRelation() )
                 role = "subarea";
-            else if( m.getType().equals(OsmPrimitiveType.NODE) ) {
+            else if( m.isNode() ) {
                 Node n = (Node)m.getMember();
                 if( !n.isIncomplete() ) {
Index: /applications/editors/josm/plugins/relcontext/src/relcontext/possible_roles.txt
===================================================================
--- /applications/editors/josm/plugins/relcontext/src/relcontext/possible_roles.txt	(revision 25692)
+++ /applications/editors/josm/plugins/relcontext/src/relcontext/possible_roles.txt	(revision 25692)
@@ -0,0 +1,11 @@
+boundary: admin_centre, label, subarea
+route: forward, backward, stop, platform
+restriction: from, to, via, location_hint
+enforcement: device, from, to, force
+destination_sign: to, from, intersection, sign
+site: perimeter, entrance, label
+bridge: across, under, outline, edge
+tunnel: through, outline, edge
+surveillance: camera, extent, visible, hidden
+street: street, address, house, associated
+collection: member, street, river, railway, address, associated
