Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 6524)
@@ -8,4 +8,5 @@
 import java.net.URL;
 import java.net.URLEncoder;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.concurrent.Future;
@@ -29,4 +30,5 @@
 import org.openstreetmap.josm.io.OsmTransferCanceledException;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
 
@@ -322,11 +324,11 @@
             if (urlString.matches(PATTERN_OSM_API_URL)) {
                 // TODO: proper i18n after stabilization
-                String message = "<ul><li>"+tr("OSM Server URL:") + " " + url.getHost() + "</li><li>" +
-                        tr("Command")+": "+url.getPath()+"</li>";
+                Collection<String> items = new ArrayList<String>();
+                items.add(tr("OSM Server URL:") + " " + url.getHost());
+                items.add(tr("Command")+": "+url.getPath());
                 if (url.getQuery() != null) {
-                    message += "<li>" + tr("Request details: {0}", url.getQuery().replaceAll(",\\s*", ", ")) + "</li>";
-                }
-                message += "</ul>";
-                return message;
+                    items.add(tr("Request details: {0}", url.getQuery().replaceAll(",\\s*", ", ")));
+                }
+                return Utils.joinAsHtmlUnorderedList(items);
             }
             // TODO: other APIs
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java	(revision 6524)
@@ -34,4 +34,5 @@
 import org.openstreetmap.josm.tools.ExceptionUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -257,15 +258,12 @@
             }
             if (!errors.isEmpty()) {
-                final StringBuilder sb = new StringBuilder();
+                final Collection<String> items = new ArrayList<String>();
                 for (Object error : errors) {
                     if (error instanceof String) {
-                        sb.append("<li>").append(error).append("</li>").append("<br>");
+                        items.add((String) error);
                     } else if (error instanceof Exception) {
-                        sb.append("<li>").append(ExceptionUtil.explainException((Exception) error)).append("</li>")
-                        .append("<br>");
+                        items.add(ExceptionUtil.explainException((Exception) error));
                     }
                 }
-                sb.insert(0, "<ul>");
-                sb.append("</ul>");
 
                 GuiHelper.runInEDT(new Runnable() {
@@ -273,5 +271,6 @@
                     public void run() {
                         JOptionPane.showMessageDialog(Main.parent, "<html>"
-                                + tr("The following errors occurred during mass download: {0}", sb.toString()) + "</html>",
+                                + tr("The following errors occurred during mass download: {0}",
+                                        Utils.joinAsHtmlUnorderedList(items)) + "</html>",
                                 tr("Errors during download"), JOptionPane.ERROR_MESSAGE);
                     }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java	(revision 6524)
@@ -5,4 +5,5 @@
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -15,4 +16,5 @@
 import org.openstreetmap.josm.gui.ExceptionDialogUtil;
 import org.openstreetmap.josm.tools.ExceptionUtil;
+import org.openstreetmap.josm.tools.Utils;
 
 public class PostDownloadHandler implements Runnable {
@@ -104,14 +106,12 @@
         //
         if (!errors.isEmpty()) {
-            final StringBuffer sb = new StringBuffer();
+            final Collection<String> items = new ArrayList<String>();
             for (Object error:errors) {
                 if (error instanceof String) {
-                    sb.append("<li>").append(error).append("</li>").append("<br>");
+                    items.add((String) error);
                 } else if (error instanceof Exception) {
-                    sb.append("<li>").append(ExceptionUtil.explainException((Exception)error)).append("</li>").append("<br>");
+                    items.add(ExceptionUtil.explainException((Exception)error));
                 }
             }
-            sb.insert(0, "<html><ul>");
-            sb.append("</ul></html>");
 
             SwingUtilities.invokeLater(new Runnable() {
@@ -120,5 +120,5 @@
                     JOptionPane.showMessageDialog(
                             Main.parent,
-                            sb.toString(),
+                            "<html>"+Utils.joinAsHtmlUnorderedList(items)+"</html>",
                             tr("Errors during download"),
                             JOptionPane.ERROR_MESSAGE);
Index: trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 6524)
@@ -189,5 +189,5 @@
                 label.setToolTipText("<html>"
                         + description
-                        + (examples.length > 0 ? ("<ul><li>" + Utils.join("</li><li>", Arrays.asList(examples)) + "</li></ul>") : "")
+                        + (examples.length > 0 ? Utils.joinAsHtmlUnorderedList(Arrays.asList(examples)) : "")
                         + "</html>");
             }
Index: trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/command/DeleteCommand.java	(revision 6524)
@@ -17,6 +17,6 @@
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
-import java.util.Map.Entry;
 
 import javax.swing.Icon;
@@ -272,5 +272,5 @@
      *    <li>it is untagged (see {@link Node#isTagged()}</li>
      *    <li>it is not referred to by other non-deleted primitives outside of  <code>primitivesToDelete</code></li>
-     * <ul>
+     * </ul>
      * @param layer  the layer in whose context primitives are deleted
      * @param primitivesToDelete  the primitives to delete
Index: trunk/src/org/openstreetmap/josm/corrector/ReverseWayNoTagCorrector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/corrector/ReverseWayNoTagCorrector.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/corrector/ReverseWayNoTagCorrector.java	(revision 6524)
@@ -15,8 +15,9 @@
 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
 import org.openstreetmap.josm.gui.DefaultNameFormatter;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
  * A ReverseWayNoTagCorrector warns about ways that should not be reversed
- * because their semantic meaning cannot be preserved in that case. 
+ * because their semantic meaning cannot be preserved in that case.
  * E.g. natural=coastline, natural=cliff, barrier=retaining_wall cannot be changed.
  * @see ReverseWayTagCorrector for handling of tags that can be modified (oneway=yes, etc.)
@@ -30,5 +31,5 @@
     
     /**
-     * Tags that imply a semantic meaning from the way direction and cannot be changed. 
+     * Tags that imply a semantic meaning from the way direction and cannot be changed.
      */
     public static final TagCollection directionalTags = new TagCollection(Arrays.asList(new Tag[]{
@@ -46,5 +47,5 @@
     
     /**
-     * Replies the tags that imply a semantic meaning from <code>way</code> direction and cannot be changed. 
+     * Replies the tags that imply a semantic meaning from <code>way</code> direction and cannot be changed.
      * @param way The way to look for
      * @return tags that imply a semantic meaning from <code>way</code> direction and cannot be changed
@@ -68,10 +69,5 @@
             return tags.iterator().next().toString();
         } else if (tags.size() > 1) {
-            StringBuilder s = new StringBuilder("<ul>");
-            for (Tag t : tags) {
-                s.append("<li>").append(t).append("</li>");
-            }
-            s.append("</ul>");
-            return s.toString();
+            return Utils.joinAsHtmlUnorderedList(tags);
         } else {
             return "";
Index: trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 6524)
@@ -480,12 +480,4 @@
         }
 
-        private static String getHtmlList(Collection<String> set) {
-            StringBuilder sb = new StringBuilder("<ul>");
-            for (String s : set) {
-                sb.append("<li>"+s+"</li>");
-            }
-            return sb.append("</ul>").toString();
-        }
-
         private void handleProxyErrors() {
             if (proxySelector.hasErrors()) {
@@ -497,7 +489,7 @@
                 ed.setIcon(JOptionPane.WARNING_MESSAGE);
                 ed.setContent(tr("JOSM tried to access the following resources:")+
-                        "<br>"+getHtmlList(proxySelector.getErrorResources())+
+                        "<br>"+Utils.joinAsHtmlUnorderedList(proxySelector.getErrorResources())+
                         tr("but <b>failed</b> to do so, because of the following proxy errors:")+
-                        "<br>"+getHtmlList(proxySelector.getErrorMessages())+
+                        "<br>"+Utils.joinAsHtmlUnorderedList(proxySelector.getErrorMessages())+
                         tr("Would you like to change your proxy settings now ?")
                         );
Index: trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMergeModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMergeModel.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMergeModel.java	(revision 6524)
@@ -36,4 +36,5 @@
 import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -358,9 +359,5 @@
         sb.append("<html>");
         sb.append(tr("The following objects could not be copied to the target object<br>because they are deleted in the target dataset:"));
-        sb.append("<ul>");
-        for (String item: items) {
-            sb.append("<li>").append(item).append("</li>");
-        }
-        sb.append("</ul>");
+        sb.append(Utils.joinAsHtmlUnorderedList(items));
         sb.append("</html>");
         HelpAwareOptionPane.showOptionDialog(
Index: trunk/src/org/openstreetmap/josm/gui/conflict/tags/RelationMemberConflictResolverTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/tags/RelationMemberConflictResolverTable.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/tags/RelationMemberConflictResolverTable.java	(revision 6524)
@@ -47,5 +47,5 @@
      * pressing TAB or ENTER. The action alters the standard navigation path from cell to cell: <ul>
      * <li>it jumps over cells in the first column</li> <li>it automatically add a new empty row
-     * when the user leaves the last cell in the table</li> <ul>
+     * when the user leaves the last cell in the table</li></ul>
      *
      *
Index: trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverTable.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverTable.java	(revision 6524)
@@ -49,5 +49,5 @@
      * pressing TAB or ENTER. The action alters the standard navigation path from cell to cell: <ul>
      * <li>it jumps over cells in the first column</li> <li>it automatically add a new empty row
-     * when the user leaves the last cell in the table</li> <ul>
+     * when the user leaves the last cell in the table</li></ul>
      *
      *
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java	(revision 6524)
@@ -156,5 +156,5 @@
      * pressing TAB or ENTER. The action alters the standard navigation path from cell to cell: <ul>
      * <li>it jumps over cells in the first column</li> <li>it automatically add a new empty row
-     * when the user leaves the last cell in the table</li> <ul>
+     * when the user leaves the last cell in the table</li></ul>
      *
      *
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 6524)
@@ -56,5 +56,5 @@
  *   <li>a dedicated version in this {@link History} called the {@link PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
  *   <li>another version in this {@link History} called the {@link PointInTimeType#CURRENT_POINT_IN_TIME}</li>
- * <ul>
+ * </ul>
  * {@link HistoryBrowser} always compares the {@link PointInTimeType#REFERENCE_POINT_IN_TIME} with the
  * {@link PointInTimeType#CURRENT_POINT_IN_TIME}.
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 6524)
@@ -63,4 +63,5 @@
 import org.openstreetmap.josm.tools.ExifReader;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
 
 import com.drew.imaging.jpeg.JpegMetadataReader;
@@ -221,9 +222,5 @@
                 sb.append(errorMessages.iterator().next());
             } else {
-                sb.append("<ul>");
-                for (String msg: errorMessages) {
-                    sb.append("<li>").append(msg).append("</li>");
-                }
-                sb.append("/ul>");
+                sb.append(Utils.joinAsHtmlUnorderedList(errorMessages));
             }
             sb.append("</html>");
Index: trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginListPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginListPanel.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginListPanel.java	(revision 6524)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.plugins.PluginInformation;
 import org.openstreetmap.josm.tools.OpenBrowser;
+import org.openstreetmap.josm.tools.Utils;
 
 public class PluginListPanel extends VerticallyScrollablePanel{
@@ -170,9 +171,6 @@
                 otherPlugins.size()
         ));
-        sb.append("<ul>");
-        for (String p: otherPlugins) {
-            sb.append("<li>").append(p).append("</li>");
-        }
-        sb.append("</ul>").append("</html>");
+        sb.append(Utils.joinAsHtmlUnorderedList(otherPlugins));
+        sb.append("</html>");
         JOptionPane.showMessageDialog(
                 parent,
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java	(revision 6524)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.gui.tagging;
 
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -45,5 +46,4 @@
 import org.openstreetmap.josm.data.osm.Tag;
 import org.openstreetmap.josm.gui.dialogs.relation.RunnableAction;
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
@@ -103,5 +103,5 @@
      *   <li>it automatically add a new empty row when the user leaves the
      *   last cell in the table</li>
-     * <ul>
+     * </ul>
      *
      */
Index: trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 6524)
@@ -64,4 +64,5 @@
 import org.openstreetmap.josm.tools.I18n;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -411,9 +412,6 @@
                 missingRequiredPlugin.size()
         ));
-        sb.append("<ul>");
-        for (String p: missingRequiredPlugin) {
-            sb.append("<li>").append(p).append("</li>");
-        }
-        sb.append("</ul>").append("</html>");
+        sb.append(Utils.joinAsHtmlUnorderedList(missingRequiredPlugin));
+        sb.append("</html>");
         JOptionPane.showMessageDialog(
                 parent,
@@ -710,9 +708,5 @@
                 "JOSM could not find information about the following plugins:",
                 plugins.size()));
-        sb.append("<ul>");
-        for (String plugin: plugins) {
-            sb.append("<li>").append(plugin).append("</li>");
-        }
-        sb.append("</ul>");
+        sb.append(Utils.joinAsHtmlUnorderedList(plugins));
         sb.append(trn("The plugin is not going to be loaded.",
                 "The plugins are not going to be loaded.",
Index: trunk/src/org/openstreetmap/josm/tools/Utils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 6523)
+++ trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 6524)
@@ -201,5 +201,10 @@
     }
 
-    public static String joinAsHtmlUnorderedList(Collection<?> values) {
+    /**
+     * Converts the given iterable collection as an unordered HTML list.
+     * @param values The iterable collection
+     * @return An unordered HTML list
+     */
+    public static String joinAsHtmlUnorderedList(Iterable<?> values) {
         StringBuilder sb = new StringBuilder(1024);
         sb.append("<ul>");
