Index: /trunk/netbeans/nbproject/project.properties
===================================================================
--- /trunk/netbeans/nbproject/project.properties	(revision 5755)
+++ /trunk/netbeans/nbproject/project.properties	(revision 5756)
@@ -1,4 +1,5 @@
 annotation.processing.enabled=false
 annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
 annotation.processing.run.all.processors=true
 annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
@@ -31,4 +32,5 @@
 file.reference.core-src=../src
 file.reference.core=..
+file.reference.test-unit=../test/unit
 includes=org/**/*.java,gnu/**/*.java,oauth/**/*.java,com/**/*.java,images/**,org/openstreetmap/gui/**/*.png,data/**,styles/**,LICENSE,README,CONTRIBUTION,gpl-2.0.txt,gpl-3.0.txt
 jar.archive.disabled=${jnlp.enabled}
@@ -67,7 +69,10 @@
 jnlp.descriptor=application
 jnlp.enabled=false
-jnlp.mixed.code=defaut
+jnlp.mixed.code=default
 jnlp.offline-allowed=false
 jnlp.signed=false
+jnlp.signing=
+jnlp.signing.alias=
+jnlp.signing.keystore=
 main.class=org.openstreetmap.josm.gui.MainApplication
 manifest.file=manifest.mf
@@ -84,2 +89,3 @@
 src.core.dir=${file.reference.core}
 src.dir=${file.reference.core-src}
+test.unit.dir=${file.reference.test-unit}
Index: /trunk/netbeans/nbproject/project.xml
===================================================================
--- /trunk/netbeans/nbproject/project.xml	(revision 5755)
+++ /trunk/netbeans/nbproject/project.xml	(revision 5756)
@@ -9,5 +9,7 @@
                 <root id="src.core.dir"/>
             </source-roots>
-            <test-roots/>
+            <test-roots>
+                <root id="test.unit.dir"/>
+            </test-roots>
         </data>
     </configuration>
Index: /trunk/src/org/openstreetmap/josm/tools/TextTagParser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/TextTagParser.java	(revision 5755)
+++ /trunk/src/org/openstreetmap/josm/tools/TextTagParser.java	(revision 5756)
@@ -1,4 +1,5 @@
 package org.openstreetmap.josm.tools;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
@@ -51,9 +52,9 @@
                 skipEmpty();
                 if (pos == n) { break; }
-                k = parseString(true);
+                k = parseString("\n\r\t= ");
                 if (pos == n) { tags.clear();  break; }
                 skipSign();
                 if (pos == n) { tags.clear();  break; }
-                v = parseString(false);
+                v = parseString("\n\r\t ");
                 tags.put(k, v);
             }
@@ -61,5 +62,7 @@
         }
         
-        private String parseString(boolean stopOnEquals) {
+        private String parseString(String stopChars) {
+            char stop[] = stopChars.toCharArray();
+            Arrays.sort(stop);
             char c;
             while (pos < n) {
@@ -81,6 +84,6 @@
                     pos++;
                     break;
-                } else if (!quotesStarted && (c=='\n'|| c=='\t'|| c==' ' || c=='\r'
-                      || (c=='=' && stopOnEquals))) {  // stop-symbols
+                } else if (!quotesStarted && (Arrays.binarySearch(stop, c)>=0)) { 
+                    // stop-symbol found
                     pos++;
                     break;
@@ -127,5 +130,5 @@
     }
 
-    private static String unescape(String k) {
+    protected static String unescape(String k) {
         if(! (k.startsWith("\"") && k.endsWith("\"")) ) {
             if (k.contains("=")) {
@@ -137,5 +140,5 @@
         }
         String text = k.substring(1,k.length()-1);
-        return (new TextAnalyzer(text)).parseString(false);
+        return (new TextAnalyzer(text)).parseString("\r\t\n");
     }
 
Index: /trunk/test/unit/org/openstreetmap/josm/tools/TextTagParserTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/tools/TextTagParserTest.java	(revision 5756)
+++ /trunk/test/unit/org/openstreetmap/josm/tools/TextTagParserTest.java	(revision 5756)
@@ -0,0 +1,94 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Preferences;
+
+public class TextTagParserTest {
+    @BeforeClass
+    public static void before() {
+        Main.pref = new Preferences();
+    }
+
+    @Test
+    public void testUnescape() {
+        String s, s1;
+        s = "\"2 3 4\"";       s1 = "2 3 4";
+        Assert.assertEquals(s1, TextTagParser.unescape(s));
+
+        s = "\"2 \\\"3\\\" 4\"";       s1 = "2 \"3\" 4";
+        Assert.assertEquals(s1, TextTagParser.unescape(s));
+        
+        s = "\"2 3 ===4===\"";       s1 = "2 3 ===4===";
+        Assert.assertEquals(s1, TextTagParser.unescape(s));
+
+        s = "\"2 3 \\\\\\\\===4===\"";       s1 = "2 3 \\\\===4===";
+        Assert.assertEquals(s1, TextTagParser.unescape(s));
+    }
+    
+    @Test
+    public void testTNformat() {
+        String txt = "   a  \t  1   \n\n\n  b=2 \t the value with \"quotes\"";
+        Map<String, String> correctTags = new HashMap<String, String>() { {
+            put("a", "1"); put("b=2", "the value with \"quotes\"");
+        }};
+        Map<String, String> tags = TextTagParser.readTagsFromText(txt);
+        Assert.assertEquals(correctTags, tags);
+    }
+
+    @Test
+    public void testEQformat() {
+        String txt = "key1=value key2=\"long value\" tag3=\"hotel \\\"Quote\\\"\"";
+        Map<String, String> correctTags = new HashMap<String, String>() { {
+            put("key1", "value"); put("key2", "long value");
+            put("tag3", "hotel \"Quote\"");
+        }};
+        Map<String, String> tags = TextTagParser.readTagsFromText(txt);
+        Assert.assertEquals(correctTags, tags);
+    }
+
+    @Test
+    public void testJSONformat() {
+        String txt;
+        Map<String, String> tags, correctTags;
+        txt = "{ \"a\":\"1\", \"b\":\"2 3 4\" }";
+        correctTags= new HashMap<String, String>() { {  put("a", "1"); put("b", "2 3 4"); }};
+        tags = TextTagParser.readTagsFromText(txt);
+        Assert.assertEquals(correctTags, tags);
+        
+        txt = "\"a\"  :     \"1 1 1\", \"b2\"  :\"2 \\\"3 qwe\\\" 4\"";
+        correctTags= new HashMap<String, String>() { { put("a", "1 1 1"); put("b2", "2 \"3 qwe\" 4");}};
+        tags = TextTagParser.readTagsFromText(txt);
+        Assert.assertEquals(correctTags, tags);
+        
+        txt = " \"aыыы\"   :    \"val\\\"\\\"\\\"ue1\"";
+        correctTags= new HashMap<String, String>() { { put("aыыы", "val\"\"\"ue1");} };
+        tags = TextTagParser.readTagsFromText(txt);
+        Assert.assertEquals(correctTags, tags);
+    }
+    
+    @Test
+    public void testFreeformat() {
+        String txt = "a 1 b=2 c=\"hello === \\\"\\\"world\"";
+        Map<String, String> correctTags = new HashMap<String, String>() { {
+            put("a", "1"); put("b", "2"); put("c", "hello === \"\"world");
+        }};
+        Map<String, String> tags = TextTagParser.readTagsFromText(txt);
+        Assert.assertEquals(correctTags, tags);
+    }
+    
+    @Test
+    public void errorDetect() {
+        String txt = "a=2 b=3 4";
+        Map<String, String> tags = TextTagParser.readTagsFromText(txt);
+        Assert.assertEquals(Collections.EMPTY_MAP, tags);
+        
+    }
+}
