Index: trunk/src/org/openstreetmap/josm/actions/ChangesetManagerToggleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ChangesetManagerToggleAction.java	(revision 4589)
+++ trunk/src/org/openstreetmap/josm/actions/ChangesetManagerToggleAction.java	(revision 4590)
@@ -34,5 +34,5 @@
                 tr("Toggle visibility of Changeset Manager window"),
                 Shortcut.registerShortcut(
-                        "menu:view:changesetdialog",
+                        "menu:windows:changesetdialog",
                         tr("Toggle visibility of Changeset Manager window"),
                         KeyEvent.VK_C,
Index: trunk/src/org/openstreetmap/josm/gui/MainMenu.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 4589)
+++ trunk/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 4590)
@@ -12,5 +12,9 @@
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JSeparator;
 import javax.swing.KeyStroke;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
 
 import org.openstreetmap.josm.Main;
@@ -56,5 +60,4 @@
 import org.openstreetmap.josm.actions.OpenLocationAction;
 import org.openstreetmap.josm.actions.OrthogonalizeAction;
-import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
 import org.openstreetmap.josm.actions.PasteAction;
 import org.openstreetmap.josm.actions.PasteTagsAction;
@@ -82,4 +85,5 @@
 import org.openstreetmap.josm.actions.ZoomInAction;
 import org.openstreetmap.josm.actions.ZoomOutAction;
+import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
 import org.openstreetmap.josm.actions.audio.AudioBackAction;
 import org.openstreetmap.josm.actions.audio.AudioFasterAction;
@@ -191,7 +195,15 @@
     public final ImageryMenu imageryMenu =
         (ImageryMenu)addMenu(new ImageryMenu(), marktr("Imagery"), KeyEvent.VK_I, 5, ht("/Menu/Imagery"));
+    /** the window menu is split into several groups. The first is for windows that can be opened from
+     * this menu any time, e.g. the changeset editor. The second group is for toggle dialogs and the third
+     * group is for currently open windows that cannot be toggled, e.g. relation editors. It's recommended
+     * to use WINDOW_MENU_GROUP to determine the group integer.
+     */
+    public final JMenu windowMenu = addMenu(marktr("Windows"), KeyEvent.VK_W, 6, ht("/Menu/Windows"));
+    public static enum WINDOW_MENU_GROUP { ALWAYS, TOGGLE_DIALOG, VOLATILE }
+
     public JMenu audioMenu = null;
-    public final JMenu helpMenu = addMenu(marktr("Help"), KeyEvent.VK_H, 6, ht("/Menu/Help"));
-    public final int defaultMenuPos = 6;
+    public final JMenu helpMenu = addMenu(marktr("Help"), KeyEvent.VK_H, 7, ht("/Menu/Help"));
+    public final int defaultMenuPos = 7;
 
     public final JosmAction moveUpAction = new MoveAction(MoveAction.Direction.UP);
@@ -203,4 +215,54 @@
     public final TaggingPresetSearchAction presetSearchAction = new TaggingPresetSearchAction();
     public FullscreenToggleAction fullscreenToggleAction = null;
+
+    /** this menu listener hides unnecessary JSeparators in a menu list but does not remove them.
+     * If at a later time the separators are required, they will be made visible again. Intended
+     * usage is make menus not look broken if separators are used to group the menu and some of
+     * these groups are empty.
+     */
+    public final static MenuListener menuSeparatorHandler = new MenuListener() {
+        @Override
+        public void menuCanceled(MenuEvent arg0) {}
+        @Override
+        public void menuDeselected(MenuEvent arg0) {}
+        @Override
+        public void menuSelected(MenuEvent a) {
+            if(!(a.getSource() instanceof JMenu))
+                return;
+            final JPopupMenu m = ((JMenu) a.getSource()).getPopupMenu();
+            for(int i=0; i < m.getComponentCount()-1; i++) {
+                if(!(m.getComponent(i) instanceof JSeparator)) {
+                    continue;
+                }
+                // hide separator if the next menu item is one as well
+                ((JSeparator) m.getComponent(i)).setVisible(!(m.getComponent(i+1) instanceof JSeparator));
+            }
+            // hide separator at the end of the menu
+            if(m.getComponent(m.getComponentCount()-1) instanceof JSeparator) {
+                ((JSeparator) m.getComponent(m.getComponentCount()-1)).setVisible(false);
+            }
+        }
+    };
+
+    /**
+     * Add a JosmAction to a menu.
+     *
+     * This method handles all the shortcut handling. It also makes sure that actions that are
+     * handled by the OS are not duplicated on the menu. Menu item will be added at the end of
+     * the menu.
+     * @param menu to add the action to
+     * @param the action that should get a menu item
+     */
+    public static JMenuItem add(JMenu menu, JosmAction action) {
+        if (action.getShortcut().getAutomatic())
+            return null;
+        JMenuItem menuitem = menu.add(action);
+            KeyStroke ks = action.getShortcut().getKeyStroke();
+            if (ks != null) {
+                menuitem.setAccelerator(ks);
+            }
+        return menuitem;
+    }
+
     /**
      * Add a JosmAction to a menu.
@@ -208,15 +270,62 @@
      * This method handles all the shortcut handling. It also makes sure that actions that are
      * handled by the OS are not duplicated on the menu.
+     * @param menu to add the action to
+     * @param the action that should get a menu item
+     * @param group the item should be added to. Groups are split by a separator.
+     *        0 is the first group, -1 will add the item to the end.
      */
-    public static JMenuItem add(JMenu menu, JosmAction action) {
-        JMenuItem menuitem = null;
-        if (!action.getShortcut().getAutomatic()) {
-            menuitem = menu.add(action);
-            KeyStroke ks = action.getShortcut().getKeyStroke();
-            if (ks != null) {
-                menuitem.setAccelerator(ks);
+    public static <E extends Enum<E>> JMenuItem add(JMenu menu, JosmAction action, Enum<E> group) {
+        if (action.getShortcut().getAutomatic())
+            return null;
+        int i = getInsertionIndexForGroup(menu, group.ordinal());
+        JMenuItem menuitem = (JMenuItem) menu.add(new JMenuItem(action), i);
+        KeyStroke ks = action.getShortcut().getKeyStroke();
+        if (ks != null) {
+            menuitem.setAccelerator(ks);
+        }
+        return menuitem;
+    }
+
+    /**
+     * Add a JosmAction to a menu and automatically prints accelerator if available.
+     * Also adds a checkbox that may be toggled.
+     * @param menu to add the action to
+     * @param the action that should get a menu item
+     * @param group the item should be added to. Groups are split by a separator. Use
+     *        one of the enums that are defined for some of the menus to tell in which
+     *        group the item should go.
+     */
+    public static <E extends Enum<E>> JCheckBoxMenuItem addWithCheckbox(JMenu menu, JosmAction action, Enum<E> group) {
+        int i = getInsertionIndexForGroup(menu, group.ordinal());
+        final JCheckBoxMenuItem mi = (JCheckBoxMenuItem) menu.add(new JCheckBoxMenuItem(action), i);
+        final KeyStroke ks = action.getShortcut().getKeyStroke();
+        if (ks != null) {
+            mi.setAccelerator(ks);
+        }
+        return mi;
+    }
+
+    /** finds the correct insertion index for a given group and adds separators if necessary */
+    private static int getInsertionIndexForGroup(JMenu menu, int group) {
+        if(group < 0)
+            return -1;
+        // look for separator that *ends* the group (or stop at end of menu)
+        int i;
+        for(i=0; i < menu.getItemCount() && group >= 0; i++) {
+            if(menu.getItem(i) == null) {
+                group--;
             }
         }
-        return menuitem;
+        // insert before separator that ends the group
+        if(group < 0) {
+            i--;
+        }
+        // not enough separators have been found, add them
+        while(group > 0) {
+            menu.addSeparator();
+            group--;
+            i++;
+        }
+        return i;
     }
 
@@ -301,12 +410,4 @@
         vft.setAccelerator(viewportFollowToggleAction.getShortcut().getKeyStroke());
         viewportFollowToggleAction.addButtonModel(vft.getModel());
-
-        // -- changeset manager toggle action
-        ChangesetManagerToggleAction changesetManagerToggleAction = new ChangesetManagerToggleAction();
-        final JCheckBoxMenuItem mi = new JCheckBoxMenuItem(changesetManagerToggleAction);
-        viewMenu.addSeparator();
-        viewMenu.add(mi);
-        mi.setAccelerator(changesetManagerToggleAction.getShortcut().getKeyStroke());
-        changesetManagerToggleAction.addButtonModel(mi.getModel());
 
         if(!Main.applet && Main.platform.canFullscreen()) {
@@ -352,4 +453,11 @@
         add(toolsMenu, createMultipolygon);
 
+        // -- changeset manager toggle action
+        ChangesetManagerToggleAction changesetManagerToggleAction = new ChangesetManagerToggleAction();
+        final JCheckBoxMenuItem mi = MainMenu.addWithCheckbox(windowMenu, changesetManagerToggleAction,
+                MainMenu.WINDOW_MENU_GROUP.ALWAYS);
+        changesetManagerToggleAction.addButtonModel(mi.getModel());
+
+
         if (!Main.pref.getBoolean("audio.menuinvisible", false)) {
             audioMenu = addMenu(marktr("Audio"), KeyEvent.VK_U, defaultMenuPos, ht("/Menu/Audio"));
@@ -370,4 +478,7 @@
         add(helpMenu, about);
 
+
+        windowMenu.addMenuListener(menuSeparatorHandler);
+
         new PresetsMenuEnabler(presetsMenu).refreshEnabled();
     }
Index: trunk/src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 4589)
+++ trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 4590)
@@ -364,11 +364,13 @@
         jb.add(toolBarActions);
 
-        jb.addSeparator(new Dimension(0,18));
-        toolBarToggle.setAlignmentX(0.5f);
-        jb.add(toolBarToggle);
-        otherButton.setAlignmentX(0.5f);
-        otherButton.setBorder(null);
-        otherButton.setFont(otherButton.getFont().deriveFont(Font.PLAIN));
-        jb.add(otherButton);
+        if(Main.pref.getBoolean("sidetoolbar.togglevisible", true)) {
+            jb.addSeparator(new Dimension(0,18));
+            toolBarToggle.setAlignmentX(0.5f);
+            jb.add(toolBarToggle);
+            otherButton.setAlignmentX(0.5f);
+            otherButton.setBorder(null);
+            otherButton.setFont(otherButton.getFont().deriveFont(Font.PLAIN));
+            jb.add(otherButton);
+        }
 
         if(Main.pref.getBoolean("sidetoolbar.visible", true))
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 4589)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 4590)
@@ -32,4 +32,5 @@
 import javax.swing.ImageIcon;
 import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JComponent;
 import javax.swing.JDialog;
@@ -42,4 +43,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.dialogs.DialogsPanel.Action;
 import org.openstreetmap.josm.gui.help.HelpUtil;
@@ -95,4 +97,9 @@
     private JPanel buttonsPanel;
 
+    /** holds the menu entry in the windows menu. Required to properly
+     * toggle the checkbox on show/hide
+     */
+    protected JCheckBoxMenuItem windowMenuItem;
+
     /**
      * Constructor
@@ -140,4 +147,8 @@
 
         RedirectInputMap.redirectToMainContentPane(this);
+
+        windowMenuItem = MainMenu.addWithCheckbox(Main.main.menu.windowMenu,
+                (JosmAction) getToggleAction(),
+                MainMenu.WINDOW_MENU_GROUP.TOGGLE_DIALOG);
     }
 
@@ -160,4 +171,7 @@
         public void actionPerformed(ActionEvent e) {
             toggleButtonHook();
+            if(getValue("toolbarbutton") != null && getValue("toolbarbutton") instanceof JButton) {
+                ((JButton) getValue("toolbarbutton")).setSelected(!isShowing);
+            }
             if (isShowing) {
                 hideDialog();
@@ -195,4 +209,5 @@
         // toggling the selected value in order to enforce PropertyChangeEvents
         setIsShowing(true);
+        windowMenuItem.setState(true);
         toggleAction.putValue("selected", false);
         toggleAction.putValue("selected", true);
@@ -252,4 +267,5 @@
         closeDetachedDialog();
         this.setVisible(false);
+        windowMenuItem.setState(false);
         setIsShowing(false);
         toggleAction.putValue("selected", false);
@@ -330,4 +346,5 @@
         closeDetachedDialog();
         hideNotify();
+        Main.main.menu.windowMenu.remove(windowMenuItem);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 4589)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 4590)
@@ -35,4 +35,6 @@
 import javax.swing.JComponent;
 import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
@@ -54,4 +56,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.CopyAction;
+import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.actions.PasteTagsAction.TagPaster;
 import org.openstreetmap.josm.command.AddCommand;
@@ -68,4 +71,5 @@
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.SideButton;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
@@ -101,4 +105,9 @@
 
     private AutoCompletingTextField tfRole;
+
+    /** the menu item in the windows menu. Required to properly
+     * hide on dialog close.
+     */
+    private JMenuItem windowMenuItem;
 
     /**
@@ -575,4 +584,7 @@
         if (visible) {
             RelationDialogManager.getRelationDialogManager().positionOnScreen(this);
+            if(windowMenuItem == null) {
+                addToWindowMenu();
+            }
         } else {
             // make sure all registered listeners are unregistered
@@ -581,6 +593,28 @@
             memberTableModel.unregister();
             memberTable.unlinkAsListener();
+            if(windowMenuItem != null) {
+                Main.main.menu.windowMenu.remove(windowMenuItem);
+                windowMenuItem = null;
+            }
             dispose();
         }
+    }
+
+    /** adds current relation editor to the windows menu (in the "volatile" group) o*/
+    protected void addToWindowMenu() {
+        String name = getRelation() == null ? tr("New Relation") : getRelation().getLocalName();
+        final String tt = tr("Focus Relation Editor with relation ''{0}'' in layer ''{1}''",
+                name, getLayer().getName());
+        name = tr("Relation Editor: {0}", name == null ? getRelation().getId() : name);
+        final JMenu wm = Main.main.menu.windowMenu;
+        final JosmAction focusAction = new JosmAction(name, "dialogs/relationlist", tt, null, false, false) {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                final RelationEditor r = (RelationEditor) getValue("relationEditor");
+                r.setVisible(true);
+            }
+        };
+        focusAction.putValue("relationEditor", this);
+        windowMenuItem = MainMenu.add(wm, focusAction, MainMenu.WINDOW_MENU_GROUP.VOLATILE);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java	(revision 4589)
+++ trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java	(revision 4590)
@@ -25,4 +25,5 @@
 import javax.swing.JDialog;
 import javax.swing.JEditorPane;
+import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
@@ -45,5 +46,7 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.OpenBrowser;
@@ -53,4 +56,9 @@
     /** the unique instance */
     private static HelpBrowser instance;
+
+    /** the menu item in the windows menu. Required to properly
+     * hide on dialog close.
+     */
+    private JMenuItem windowMenuItem;
 
     /**
@@ -106,4 +114,11 @@
 
     private HelpContentReader reader;
+
+    private static final JosmAction focusAction = new JosmAction(tr("JOSM Help Browser"), "help", "", null, false, false) {
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            HelpBrowser.getInstance().setVisible(true);
+        }
+    };
 
     /**
@@ -193,4 +208,11 @@
         } else if (!visible && isShowing()){
             new WindowGeometry(this).remember(getClass().getName() + ".geometry");
+        }
+        if(windowMenuItem != null && !visible) {
+            Main.main.menu.windowMenu.remove(windowMenuItem);
+            windowMenuItem = null;
+        }
+        if(windowMenuItem == null && visible) {
+            windowMenuItem = MainMenu.add(Main.main.menu.windowMenu, focusAction, MainMenu.WINDOW_MENU_GROUP.VOLATILE);
         }
         super.setVisible(visible);
