Index: /trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java	(revision 9643)
+++ /trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java	(revision 9644)
@@ -8,4 +8,5 @@
 import java.awt.BorderLayout;
 import java.awt.Dimension;
+import java.awt.GraphicsEnvironment;
 import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
@@ -58,12 +59,37 @@
  * Help browser displaying HTML pages fetched from JOSM wiki.
  */
-public class HelpBrowser extends JDialog {
+public class HelpBrowser extends JDialog implements IHelpBrowser {
+
     /** the unique instance */
     private static HelpBrowser instance;
 
-    /** the menu item in the windows menu. Required to properly
-     * hide on dialog close.
-     */
+    /** the menu item in the windows menu. Required to properly hide on dialog close */
     private JMenuItem windowMenuItem;
+
+    /** the help browser */
+    private JosmEditorPane help;
+
+    /** the help browser history */
+    private transient HelpBrowserHistory history;
+
+    /** the currently displayed URL */
+    private String url;
+
+    private final transient 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);
+        }
+    };
+
+    /**
+     * Constructs a new {@code HelpBrowser}.
+     */
+    public HelpBrowser() {
+        reader = new HelpContentReader(HelpUtil.getWikiBaseUrl());
+        build();
+    }
 
     /**
@@ -110,22 +136,4 @@
     }
 
-    /** the help browser */
-    private JosmEditorPane help;
-
-    /** the help browser history */
-    private transient HelpBrowserHistory history;
-
-    /** the currently displayed URL */
-    private String url;
-
-    private final transient 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);
-        }
-    };
-
     /**
      * Builds the style sheet used in the internal help browser
@@ -136,11 +144,11 @@
         StyleSheet ss = new StyleSheet();
         StringBuilder css = new StringBuilder();
-        try (BufferedReader reader = new BufferedReader(
+        try (BufferedReader breader = new BufferedReader(
                 new InputStreamReader(
                         getClass().getResourceAsStream("/data/help-browser.css"), StandardCharsets.UTF_8
                 )
         )) {
-            String line = null;
-            while ((line = reader.readLine()) != null) {
+            String line;
+            while ((line = breader.readLine()) != null) {
                 css.append(line);
                 css.append('\n');
@@ -157,11 +165,11 @@
     protected JToolBar buildToolBar() {
         JToolBar tb = new JToolBar();
-        tb.add(new JButton(new HomeAction()));
-        tb.add(new JButton(new BackAction(history)));
-        tb.add(new JButton(new ForwardAction(history)));
-        tb.add(new JButton(new ReloadAction()));
+        tb.add(new JButton(new HomeAction(this)));
+        tb.add(new JButton(new BackAction(this)));
+        tb.add(new JButton(new ForwardAction(this)));
+        tb.add(new JButton(new ReloadAction(this)));
         tb.add(new JSeparator());
-        tb.add(new JButton(new OpenInBrowserAction()));
-        tb.add(new JButton(new EditAction()));
+        tb.add(new JButton(new OpenInBrowserAction(this)));
+        tb.add(new JButton(new EditAction(this)));
         return tb;
     }
@@ -226,12 +234,4 @@
     }
 
-    /**
-     * Constructs a new {@code HelpBrowser}.
-     */
-    public HelpBrowser() {
-        reader = new HelpContentReader(HelpUtil.getWikiBaseUrl());
-        build();
-    }
-
     protected void loadTopic(String content) {
         Document document = help.getEditorKit().createDefaultDocument();
@@ -244,9 +244,5 @@
     }
 
-    /**
-     * Replies the current URL
-     *
-     * @return the current URL
-     */
+    @Override
     public String getUrl() {
         return url;
@@ -363,12 +359,5 @@
     }
 
-    /**
-     * Opens an URL and displays the content.
-     *
-     *  If the URL is the locator of an absolute help topic, help content is loaded from
-     *  the JOSM wiki. Otherwise, the help browser loads the page from the given URL
-     *
-     * @param url the url
-     */
+    @Override
     public void openUrl(String url) {
         if (!isVisible()) {
@@ -410,10 +399,5 @@
     }
 
-    /**
-     * Loads and displays the help information for a help topic given
-     * by a relative help topic name, i.e. "/Action/New"
-     *
-     * @param relativeHelpTopic the relative help topic
-     */
+    @Override
     public void openHelpTopic(String relativeHelpTopic) {
         if (!isVisible()) {
@@ -426,6 +410,20 @@
     }
 
-    class OpenInBrowserAction extends AbstractAction {
-        OpenInBrowserAction() {
+    abstract static class AbstractBrowserAction extends AbstractAction {
+        protected final transient IHelpBrowser browser;
+
+        protected AbstractBrowserAction(IHelpBrowser browser) {
+            this.browser = browser;
+        }
+    }
+
+    static class OpenInBrowserAction extends AbstractBrowserAction {
+
+        /**
+         * Constructs a new {@code OpenInBrowserAction}.
+         * @param browser help browser
+         */
+        OpenInBrowserAction(IHelpBrowser browser) {
+            super(browser);
             putValue(SHORT_DESCRIPTION, tr("Open the current help page in an external browser"));
             putValue(SMALL_ICON, ImageProvider.get("help", "internet"));
@@ -434,13 +432,16 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            OpenBrowser.displayUrl(getUrl());
-        }
-    }
-
-    class EditAction extends AbstractAction {
+            OpenBrowser.displayUrl(browser.getUrl());
+        }
+    }
+
+    static class EditAction extends AbstractBrowserAction {
+
         /**
          * Constructs a new {@code EditAction}.
-         */
-        EditAction() {
+         * @param browser help browser
+         */
+        EditAction(IHelpBrowser browser) {
+            super(browser);
             putValue(SHORT_DESCRIPTION, tr("Edit the current help page"));
             putValue(SMALL_ICON, ImageProvider.get("dialogs", "edit"));
@@ -449,5 +450,5 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            String url = getUrl();
+            String url = browser.getUrl();
             if (url == null)
                 return;
@@ -457,13 +458,15 @@
                         + "is an external URL. Editing is only possible for help topics<br>"
                         + "on the help server <tt>{1}</tt>.</html>",
-                        getUrl(),
+                        url,
                         HelpUtil.getWikiBaseUrl()
                 );
-                JOptionPane.showMessageDialog(
-                        Main.parent,
-                        message,
-                        tr("Warning"),
-                        JOptionPane.WARNING_MESSAGE
-                );
+                if (!GraphicsEnvironment.isHeadless()) {
+                    JOptionPane.showMessageDialog(
+                            Main.parent,
+                            message,
+                            tr("Warning"),
+                            JOptionPane.WARNING_MESSAGE
+                    );
+                }
                 return;
             }
@@ -473,6 +476,12 @@
     }
 
-    class ReloadAction extends AbstractAction {
-        ReloadAction() {
+    static class ReloadAction extends AbstractBrowserAction {
+
+        /**
+         * Constructs a new {@code ReloadAction}.
+         * @param browser help browser
+         */
+        ReloadAction(IHelpBrowser browser) {
+            super(browser);
             putValue(SHORT_DESCRIPTION, tr("Reload the current help page"));
             putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
@@ -481,57 +490,66 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            openUrl(getUrl());
-        }
-    }
-
-    static class BackAction extends AbstractAction implements Observer {
-        private final transient HelpBrowserHistory history;
-
-        BackAction(HelpBrowserHistory history) {
-            this.history = history;
-            history.addObserver(this);
+            browser.openUrl(browser.getUrl());
+        }
+    }
+
+    static class BackAction extends AbstractBrowserAction implements Observer {
+
+        /**
+         * Constructs a new {@code BackAction}.
+         * @param browser help browser
+         */
+        BackAction(IHelpBrowser browser) {
+            super(browser);
+            browser.getHistory().addObserver(this);
             putValue(SHORT_DESCRIPTION, tr("Go to the previous page"));
             putValue(SMALL_ICON, ImageProvider.get("help", "previous"));
-            setEnabled(history.canGoBack());
+            setEnabled(browser.getHistory().canGoBack());
         }
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            history.back();
+            browser.getHistory().back();
         }
 
         @Override
         public void update(Observable o, Object arg) {
-            setEnabled(history.canGoBack());
-        }
-    }
-
-    static class ForwardAction extends AbstractAction implements Observer {
-        private final transient HelpBrowserHistory history;
-
-        ForwardAction(HelpBrowserHistory history) {
-            this.history = history;
-            history.addObserver(this);
+            setEnabled(browser.getHistory().canGoBack());
+        }
+    }
+
+    static class ForwardAction extends AbstractBrowserAction implements Observer {
+
+        /**
+         * Constructs a new {@code ForwardAction}.
+         * @param browser help browser
+         */
+        ForwardAction(IHelpBrowser browser) {
+            super(browser);
+            browser.getHistory().addObserver(this);
             putValue(SHORT_DESCRIPTION, tr("Go to the next page"));
             putValue(SMALL_ICON, ImageProvider.get("help", "next"));
-            setEnabled(history.canGoForward());
+            setEnabled(browser.getHistory().canGoForward());
         }
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            history.forward();
+            browser.getHistory().forward();
         }
 
         @Override
         public void update(Observable o, Object arg) {
-            setEnabled(history.canGoForward());
-        }
-    }
-
-    class HomeAction extends AbstractAction  {
+            setEnabled(browser.getHistory().canGoForward());
+        }
+    }
+
+    static class HomeAction extends AbstractBrowserAction {
+
         /**
          * Constructs a new {@code HomeAction}.
-         */
-        HomeAction() {
+         * @param browser help browser
+         */
+        HomeAction(IHelpBrowser browser) {
+            super(browser);
             putValue(SHORT_DESCRIPTION, tr("Go to the JOSM help home page"));
             putValue(SMALL_ICON, ImageProvider.get("help", "home"));
@@ -540,5 +558,5 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            openHelpTopic("/");
+            browser.openHelpTopic("/");
         }
     }
@@ -576,6 +594,5 @@
          * Checks whether the hyperlink event originated on a &lt;a ...&gt; element with
          * a relative href consisting of a URL fragment only, i.e.
-         * &lt;a href="#thisIsALocalFragment"&gt;. If so, replies the fragment, i.e.
-         * "thisIsALocalFragment".
+         * &lt;a href="#thisIsALocalFragment"&gt;. If so, replies the fragment, i.e. "thisIsALocalFragment".
          *
          * Otherwise, replies <code>null</code>
@@ -587,8 +604,10 @@
             AttributeSet set = e.getSourceElement().getAttributes();
             Object value = set.getAttribute(Tag.A);
-            if (!(value instanceof SimpleAttributeSet)) return null;
+            if (!(value instanceof SimpleAttributeSet))
+                return null;
             SimpleAttributeSet atts = (SimpleAttributeSet) value;
             value = atts.getAttribute(javax.swing.text.html.HTML.Attribute.HREF);
-            if (value == null) return null;
+            if (value == null)
+                return null;
             String s = (String) value;
             if (s.matches("#.*"))
@@ -632,3 +651,8 @@
         }
     }
+
+    @Override
+    public HelpBrowserHistory getHistory() {
+        return history;
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/help/HelpBrowserHistory.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/help/HelpBrowserHistory.java	(revision 9643)
+++ /trunk/src/org/openstreetmap/josm/gui/help/HelpBrowserHistory.java	(revision 9644)
@@ -7,14 +7,25 @@
 import java.util.Observable;
 
+/**
+ * Help browser history.
+ * @since 2274
+ */
 public class HelpBrowserHistory extends Observable {
-    private final HelpBrowser browser;
+    private final IHelpBrowser browser;
     private List<String> history;
     private int historyPos;
 
-    public HelpBrowserHistory(HelpBrowser browser) {
+    /**
+     * Constructs a new {@code HelpBrowserHistory}.
+     * @param browser help browser
+     */
+    public HelpBrowserHistory(IHelpBrowser browser) {
         this.browser = browser;
         history = new ArrayList<>();
     }
 
+    /**
+     * Clears the history.
+     */
     public void clear() {
         history.clear();
@@ -24,15 +35,27 @@
     }
 
+    /**
+     * Determines if the help browser can go back.
+     * @return {@code true} if a previous history position exists
+     */
     public boolean canGoBack() {
         return historyPos > 0;
     }
 
+    /**
+     * Determines if the help browser can go forward.
+     * @return {@code true} if a following history position exists
+     */
     public boolean canGoForward() {
         return historyPos + 1 < history.size();
     }
 
+    /**
+     * Go back.
+     */
     public void back() {
         historyPos--;
-        if (historyPos < 0) return;
+        if (historyPos < 0)
+            return;
         String url = history.get(historyPos);
         browser.openUrl(url);
@@ -41,7 +64,11 @@
     }
 
+    /**
+     * Go forward.
+     */
     public void forward() {
         historyPos++;
-        if (historyPos >= history.size()) return;
+        if (historyPos >= history.size())
+            return;
         String url = history.get(historyPos);
         browser.openUrl(url);
@@ -50,4 +77,8 @@
     }
 
+    /**
+     * Remembers the new current URL.
+     * @param url the new current URL
+     */
     public void setCurrentUrl(String url) {
         boolean add = true;
Index: /trunk/src/org/openstreetmap/josm/gui/help/IHelpBrowser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/help/IHelpBrowser.java	(revision 9644)
+++ /trunk/src/org/openstreetmap/josm/gui/help/IHelpBrowser.java	(revision 9644)
@@ -0,0 +1,39 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.help;
+
+/**
+ * Help browser super interface.
+ * @since 9644
+ */
+interface IHelpBrowser {
+
+    /**
+     * Replies the current URL.
+     * @return the current URL
+     */
+    String getUrl();
+
+    /**
+     * Replies the browser history.
+     * @return the browser history
+     */
+    HelpBrowserHistory getHistory();
+
+    /**
+     * Loads and displays the help information for a help topic given
+     * by a relative help topic name, i.e. "/Action/New".
+     *
+     * @param relativeHelpTopic the relative help topic
+     */
+    void openHelpTopic(String relativeHelpTopic);
+
+    /**
+     * Opens an URL and displays the content.
+     *
+     * If the URL is the locator of an absolute help topic, help content is loaded from
+     * the JOSM wiki. Otherwise, the help browser loads the page from the given URL.
+     *
+     * @param url the url
+     */
+    void openUrl(String url);
+}
Index: /trunk/test/unit/org/openstreetmap/josm/gui/help/HelpBrowserTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/help/HelpBrowserTest.java	(revision 9644)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/help/HelpBrowserTest.java	(revision 9644)
@@ -0,0 +1,125 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.help;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.tools.LanguageInfo.LocaleType;
+
+/**
+ * Unit tests of {@link HelpBrowser} class.
+ */
+public class HelpBrowserTest {
+
+    private static final String URL_1 = "https://josm.openstreetmap.de/wiki/Help";
+    private static final String URL_2 = "https://josm.openstreetmap.de/wiki/Introduction";
+    private static final String URL_3 = "https://josm.openstreetmap.de/javadoc";
+
+    /**
+     * Setup tests
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() {
+        JOSMFixture.createUnitTestFixture().init();
+    }
+
+    static IHelpBrowser newHelpBrowser() {
+        return new IHelpBrowser() {
+
+            private final HelpBrowserHistory history = new HelpBrowserHistory(this);
+            private String url;
+
+            @Override
+            public void openUrl(String url) {
+                history.setCurrentUrl(url);
+                this.url = url;
+            }
+
+            @Override
+            public void openHelpTopic(String relativeHelpTopic) {
+                openUrl(HelpUtil.getHelpTopicUrl(HelpUtil.buildAbsoluteHelpTopic(relativeHelpTopic, LocaleType.ENGLISH)));
+            }
+
+            @Override
+            public String getUrl() {
+                return url;
+            }
+
+            @Override
+            public HelpBrowserHistory getHistory() {
+                return history;
+            }
+        };
+    }
+
+    /**
+     * Unit test of {@link HelpBrowser.BackAction} and {@link HelpBrowser.ForwardAction} classes.
+     */
+    @Test
+    public void testBackAndForwardActions() {
+        IHelpBrowser browser = newHelpBrowser();
+        browser.openUrl(URL_1);
+        assertEquals(URL_1, browser.getUrl());
+        browser.openUrl(URL_2);
+        assertEquals(URL_2, browser.getUrl());
+        new HelpBrowser.BackAction(browser).actionPerformed(null);
+        assertEquals(URL_1, browser.getUrl());
+        new HelpBrowser.ForwardAction(browser).actionPerformed(null);
+        assertEquals(URL_2, browser.getUrl());
+    }
+
+    /**
+     * Unit test of {@link HelpBrowser.HomeAction} class.
+     */
+    @Test
+    public void testHomeAction() {
+        IHelpBrowser browser = newHelpBrowser();
+        assertNull(browser.getUrl());
+        new HelpBrowser.HomeAction(browser).actionPerformed(null);
+        assertEquals(URL_1, browser.getUrl());
+    }
+
+    /**
+     * Unit test of {@link HelpBrowser.EditAction} class.
+     */
+    @Test
+    public void testEditAction() {
+        IHelpBrowser browser = newHelpBrowser();
+        assertNull(browser.getUrl());
+        new HelpBrowser.EditAction(browser).actionPerformed(null);
+
+        browser.openUrl(URL_2);
+        assertEquals(URL_2, browser.getUrl());
+        new HelpBrowser.EditAction(browser).actionPerformed(null);
+
+        browser.openUrl(URL_3);
+        assertEquals(URL_3, browser.getUrl());
+        new HelpBrowser.EditAction(browser).actionPerformed(null);
+    }
+
+    /**
+     * Unit test of {@link HelpBrowser.OpenInBrowserAction} class.
+     */
+    @Test
+    public void testOpenInBrowserAction() {
+        IHelpBrowser browser = newHelpBrowser();
+        browser.openUrl(URL_1);
+        assertEquals(URL_1, browser.getUrl());
+        new HelpBrowser.OpenInBrowserAction(browser).actionPerformed(null);
+    }
+
+    /**
+     * Unit test of {@link HelpBrowser.ReloadAction} class.
+     */
+    @Test
+    public void testReloadAction() {
+        IHelpBrowser browser = newHelpBrowser();
+        browser.openUrl(URL_1);
+        assertEquals(URL_1, browser.getUrl());
+        new HelpBrowser.ReloadAction(browser).actionPerformed(null);
+        assertEquals(URL_1, browser.getUrl());
+    }
+}
