Index: /trunk/src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 1627)
+++ /trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 1628)
@@ -22,5 +22,4 @@
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.gui.historycombobox.StringUtils;
 import org.openstreetmap.josm.gui.historycombobox.SuggestingJHistoryComboBox;
 import org.openstreetmap.josm.io.OsmServerWriter;
@@ -38,6 +37,6 @@
  */
 public class UploadAction extends JosmAction {
-    
-    public static final String HISTORY_KEY = "upload.comment.history"; 
+
+    public static final String HISTORY_KEY = "upload.comment.history";
 
     /** Upload Hook */
@@ -103,8 +102,8 @@
                     p.add(new JScrollPane(l), GBC.eol().fill());
                 }
-                
+
                 p.add(new JLabel(tr("Provide a brief comment for the changes you are uploading:")), GBC.eol().insets(0, 5, 10, 3));
                 SuggestingJHistoryComboBox cmt = new SuggestingJHistoryComboBox();
-                List<String> cmtHistory = StringUtils.stringToList(Main.pref.get(HISTORY_KEY), SuggestingJHistoryComboBox.DELIM);
+                List<String> cmtHistory = new LinkedList<String>(Main.pref.getCollection(HISTORY_KEY, null));
                 cmt.setHistory(cmtHistory);
                 //final JTextField cmt = new JTextField(lastCommitComment);
@@ -112,20 +111,20 @@
 
                 while(true) {
-                    int result = new ExtendedDialog(Main.parent, 
-                        tr("Upload these changes?"), 
+                    int result = new ExtendedDialog(Main.parent,
+                        tr("Upload these changes?"),
                         p,
-                        new String[] {tr("Upload Changes"), tr("Cancel")}, 
+                        new String[] {tr("Upload Changes"), tr("Cancel")},
                         new String[] {"upload.png", "cancel.png"}).getValue();
-                    
+
                     // cancel pressed
                     if (result != 1) return false;
-                    
+
                     // don't allow empty commit message
                     if (cmt.getText().trim().length() < 3) continue;
-                    
+
                     // store the history of comments
                     cmt.addCurrentItemToHistory();
-                    Main.pref.put(HISTORY_KEY, StringUtils.listToString(cmt.getHistory(), SuggestingJHistoryComboBox.DELIM));
-                    
+                    Main.pref.putCollection(HISTORY_KEY, cmt.getHistory());
+
                     break;
                 }
Index: /trunk/src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 1627)
+++ /trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 1628)
@@ -7,7 +7,9 @@
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -279,5 +281,6 @@
         try {
             setSystemProperties();
-            final PrintWriter out = new PrintWriter(new FileWriter(getPreferencesDir() + "preferences"), false);
+            final PrintWriter out = new PrintWriter(new OutputStreamWriter(
+            new FileOutputStream(getPreferencesDir() + "preferences"), "utf-8"), false);
             for (final Entry<String, String> e : properties.entrySet()) {
                 String s = defaults.get(e.getKey());
@@ -296,5 +299,6 @@
     public void load() throws IOException {
         properties.clear();
-        final BufferedReader in = new BufferedReader(new FileReader(getPreferencesDir()+"preferences"));
+        final BufferedReader in = new BufferedReader(new InputStreamReader(
+        new FileInputStream(getPreferencesDir()+"preferences"), "utf-8"));
         int lineNumber = 0;
         ArrayList<Integer> errLines = new ArrayList<Integer>();
@@ -362,10 +366,11 @@
         if (!bookmarkFile.exists())
             bookmarkFile.createNewFile();
-        BufferedReader in = new BufferedReader(new FileReader(bookmarkFile));
+        BufferedReader in = new BufferedReader(new InputStreamReader(
+        new FileInputStream(bookmarkFile), "utf-8"));
 
         LinkedList<Bookmark> bookmarks = new LinkedList<Bookmark>();
-        // use pattern matches to scan text, as text may contain a "," itself
         for (String line = in.readLine(); line != null; line = in.readLine()) {
-            Matcher m = Pattern.compile("^(.+),(-?\\d+.\\d+),(-?\\d+.\\d+),(-?\\d+.\\d+),(-?\\d+.\\d+)$").matcher(line);
+            // FIXME: legacy code using ',' sign, should be \u001e only
+            Matcher m = Pattern.compile("^(.+)[,\u001e](-?\\d+.\\d+)[,\u001e](-?\\d+.\\d+)[,\u001e](-?\\d+.\\d+)[,\u001e](-?\\d+.\\d+)$").matcher(line);
             if(m.matches())
             {
@@ -386,9 +391,10 @@
         if (!bookmarkFile.exists())
             bookmarkFile.createNewFile();
-        PrintWriter out = new PrintWriter(new FileWriter(bookmarkFile));
+        PrintWriter out = new PrintWriter(new OutputStreamWriter(
+        new FileOutputStream(bookmarkFile), "utf-8"));
         for (Bookmark b : bookmarks) {
-            out.print(b.name+",");
+            out.print(b.name+"\u001e");
             for (int i = 0; i < b.latlon.length; ++i)
-                out.print(b.latlon[i]+(i<b.latlon.length-1?",":""));
+                out.print(b.latlon[i]+(i<b.latlon.length-1?"\u001e":""));
             out.println();
         }
@@ -491,5 +497,5 @@
             {
                 if(d != null)
-                    d += ";" + a;
+                    d += "\u001e" + a;
                 else
                     d = a;
@@ -498,5 +504,20 @@
         }
         if(s != null && s.length() != 0)
-           return Arrays.asList(s.split(";"));
+        {
+            if(s.indexOf("\u001e") < 0) /* FIXME: legacy code, remove later */
+            {
+                String r =s;
+                if(r.indexOf("§§§") > 0) /* history dialog */
+                    r = r.replaceAll("§§§","\u001e");
+                else /* old style ';' separation */
+                    r = r.replace(';','\u001e');
+                if(!r.equals(s)) /* save the converted string */
+                {
+                    put(key,r);
+                    s = r;
+                }
+            }
+            return Arrays.asList(s.split("\u001e"));
+        }
         return def;
     }
@@ -516,5 +537,5 @@
             {
                 if(s != null)
-                    s += ";" + a;
+                    s += "\u001e" + a;
                 else
                     s = a;
Index: /trunk/src/org/openstreetmap/josm/gui/historycombobox/JHistoryComboBox.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/historycombobox/JHistoryComboBox.java	(revision 1627)
+++ /trunk/src/org/openstreetmap/josm/gui/historycombobox/JHistoryComboBox.java	(revision 1628)
@@ -1,17 +1,17 @@
 /* Copyright (c) 2008, Henrik Niehaus
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
- * 
+ *
  * 1. Redistributions of source code must retain the above copyright notice,
  *    this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice, 
- *    this list of conditions and the following disclaimer in the documentation 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its 
- *    contributors may be used to endorse or promote products derived from this 
+ * 3. Neither the name of the project nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
  *    software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -35,5 +35,5 @@
 
 /**
- * Extends the standard JComboBox with a history. Works with Strings only. 
+ * Extends the standard JComboBox with a history. Works with Strings only.
  * @author henni
  *
@@ -41,13 +41,11 @@
 public class JHistoryComboBox extends JComboBox implements ActionListener {
 
-    public static String DELIM = "§§§";
-    
     protected ComboBoxHistory model;
-    
+
     /**
      * Default constructor for GUI editors. Don't use this!!!
      */
     public JHistoryComboBox() {}
-    
+
     /**
      * @param history the history as a list of strings
@@ -60,5 +58,5 @@
         setHistory(history);
     }
-    
+
     public void actionPerformed(ActionEvent e) {
         addCurrentItemToHistory();
@@ -69,25 +67,25 @@
         model.addElement(regex);
     }
-    
+
     public void setText(String text) {
-    	getEditor().setItem(text);
+        getEditor().setItem(text);
     }
-    
+
     public String getText() {
-    	return getEditor().getItem().toString();
+        return getEditor().getItem().toString();
     }
-    
+
     public void addHistoryChangedListener(HistoryChangedListener l) {
         model.addHistoryChangedListener(l);
     }
-    
+
     public void removeHistoryChangedListener(HistoryChangedListener l) {
         model.removeHistoryChangedListener(l);
     }
-    
+
     public void setHistory(List<String> history) {
         model.setItems(history);
     }
-    
+
     public List<String> getHistory() {
         return model.asList();
Index: unk/src/org/openstreetmap/josm/gui/historycombobox/StringUtils.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/historycombobox/StringUtils.java	(revision 1627)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package org.openstreetmap.josm.gui.historycombobox;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-public class StringUtils {
-    public static List<String> stringToList(String string, String delim) {
-        List<String> list = new ArrayList<String>();
-        if(string != null && delim != null) {
-            String[] s = string.split(delim);
-            for (String str : s) {
-                list.add(str);
-            }
-        }
-        return list;
-    }
-    
-    public static String listToString(List<String> list, String delim) {
-        if(list != null && list.size() > 0) {
-            Iterator<String> iter = list.iterator();
-            StringBuilder sb = new StringBuilder(iter.next());
-            while(iter.hasNext()) {
-                sb.append(delim).append(iter.next());
-            }
-            return sb.toString();
-        }
-        return "";
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/gui/historycombobox/SuggestingJHistoryComboBox.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/historycombobox/SuggestingJHistoryComboBox.java	(revision 1627)
+++ /trunk/src/org/openstreetmap/josm/gui/historycombobox/SuggestingJHistoryComboBox.java	(revision 1628)
@@ -1,17 +1,17 @@
 /* Copyright (c) 2008, Henrik Niehaus
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
- * 
+ *
  * 1. Redistributions of source code must retain the above copyright notice,
  *    this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice, 
- *    this list of conditions and the following disclaimer in the documentation 
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its 
- *    contributors may be used to endorse or promote products derived from this 
+ * 3. Neither the name of the project nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
  *    software without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -43,6 +43,6 @@
 public class SuggestingJHistoryComboBox extends JHistoryComboBox implements KeyListener {
 
-	private EventConsumingPlainDocument doc = new EventConsumingPlainDocument();
-	
+    private EventConsumingPlainDocument doc = new EventConsumingPlainDocument();
+
     public SuggestingJHistoryComboBox(List<String> history) {
         super(history);
@@ -50,32 +50,32 @@
         // add keylistener for ctrl + space
         getEditor().getEditorComponent().addKeyListener(this);
-        
+
         // add specialized document, which can consume events, which are
         // produced by the suggestion
         ((JTextComponent)getEditor().getEditorComponent()).setDocument(doc);
-        
+
         // add DocumentFilter to trigger suggestion
         JTextField editor = (JTextField) getEditor().getEditorComponent();
         final AbstractDocument doc = (AbstractDocument) editor.getDocument();
         doc.setDocumentFilter(new DocumentFilter() {
-			@Override
-			public void insertString(FilterBypass fb, int offset,
-					String string, AttributeSet attr)
-					throws BadLocationException {
-				super.insertString(fb, offset, string, attr);
-				if(doc.getLength() > 0) {
-					suggest();
-				}
-			}
+            @Override
+            public void insertString(FilterBypass fb, int offset,
+                    String string, AttributeSet attr)
+                    throws BadLocationException {
+                super.insertString(fb, offset, string, attr);
+                if(doc.getLength() > 0) {
+                    suggest();
+                }
+            }
 
-			@Override
-			public void replace(FilterBypass fb, int offset, int length,
-					String text, AttributeSet attrs)
-					throws BadLocationException {
-				super.replace(fb, offset, length, text, attrs);
-				if(doc.getLength() > 0) {
-					suggest();
-				}
-			}
+            @Override
+            public void replace(FilterBypass fb, int offset, int length,
+                    String text, AttributeSet attrs)
+                    throws BadLocationException {
+                super.replace(fb, offset, length, text, attrs);
+                if(doc.getLength() > 0) {
+                    suggest();
+                }
+            }
         });
     }
@@ -89,5 +89,5 @@
         if(e.getSource() instanceof JTextField) {
             JTextField textField = (JTextField) e.getSource();
-    
+
             // if the ActionCommand equals SUGGEST, the user confirms a suggestion
             if("SUGGEST".equals(e.getActionCommand())) {
@@ -102,29 +102,29 @@
 
     private void suggest() {
-		JTextField textField = (JTextField) getEditor().getEditorComponent();
-		String text = textField.getText();
+        JTextField textField = (JTextField) getEditor().getEditorComponent();
+        String text = textField.getText();
 
-		// suggest text
-		for (String suggestion : super.model) {
-			if (suggestion.startsWith(text)) {
-				textField.setActionCommand("SUGGEST");
-				doc.setConsumeEvents(true);
-				// avoid unbound recursion via setText() -> replace() -> 
-				// suggest() -> setText() ... in some environments
-				if (! text.equals(suggestion)) {
-				    textField.setText(suggestion);
-				}
-				textField.setSelectionStart(text.length());
-				textField.setSelectionEnd(textField.getText().length());
-				doc.setConsumeEvents(false);
-				break;
-			}
-		}
-	}
-    
+        // suggest text
+        for (String suggestion : super.model) {
+            if (suggestion.startsWith(text)) {
+                textField.setActionCommand("SUGGEST");
+                doc.setConsumeEvents(true);
+                // avoid unbound recursion via setText() -> replace() ->
+                // suggest() -> setText() ... in some environments
+                if (! text.equals(suggestion)) {
+                    textField.setText(suggestion);
+                }
+                textField.setSelectionStart(text.length());
+                textField.setSelectionEnd(textField.getText().length());
+                doc.setConsumeEvents(false);
+                break;
+            }
+        }
+    }
+
     public void keyReleased(KeyEvent e) {
-    	if(e.getKeyCode() == KeyEvent.VK_SPACE && e.isControlDown()) {
-        	suggest();
-        } 
+        if(e.getKeyCode() == KeyEvent.VK_SPACE && e.isControlDown()) {
+            suggest();
+        }
     }
     public void keyPressed(KeyEvent e) {}
Index: /trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1627)
+++ /trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 1628)
@@ -15,5 +15,4 @@
 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
 import org.openstreetmap.josm.gui.historycombobox.JHistoryComboBox;
-import org.openstreetmap.josm.gui.historycombobox.StringUtils;
 
 /**
@@ -34,8 +33,7 @@
      */
     public Collection<OsmPrimitive> processed;
-   
 
     private OsmApi api = new OsmApi();
-    
+
     private static final int MSECS_PER_SECOND = 1000;
     private static final int SECONDS_PER_MINUTE = 60;
@@ -62,5 +60,5 @@
 
     /**
-     * Send the dataset to the server. 
+     * Send the dataset to the server.
      * @param the_version version of the data set
      * @param list list of objects to send
@@ -68,5 +66,5 @@
     public void uploadOsm(String the_version, Collection<OsmPrimitive> list) {
         processed = new LinkedList<OsmPrimitive>();
-        
+
         // initialize API. Abort upload in case of configuration or network
         // errors
@@ -87,5 +85,4 @@
             return;
         }
-        
 
         Main.pleaseWaitDlg.progress.setMaximum(list.size());
@@ -93,5 +90,5 @@
 
         boolean useChangesets = api.hasChangesetSupport();
-        
+
         // controls whether or not we try and upload the whole bunch in one go
         boolean useDiffUploads = Main.pref.getBoolean("osm-server.atomic-upload",
@@ -103,5 +100,5 @@
                 // add the last entered comment to the changeset
                 String cmt = "";
-                List<String> history = StringUtils.stringToList(Main.pref.get(UploadAction.HISTORY_KEY), JHistoryComboBox.DELIM);
+                List<String> history = new LinkedList<String>(Main.pref.getCollection(UploadAction.HISTORY_KEY, null));
                 if(history.size() > 0) {
                     cmt = history.get(0);
@@ -161,8 +158,8 @@
             // has successfully cancelled the data upload
             //
-            return; 
+            return;
         }
-        
-        JOptionPane.showMessageDialog(Main.parent, 
+
+        JOptionPane.showMessageDialog(Main.parent,
             /* tr("Error during upload: ") + */ e.getMessage());
     }
