Index: applications/editors/josm/plugins/utilsplugin2/build.xml
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 29226)
+++ applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 29234)
@@ -31,5 +31,5 @@
 
     <!-- enter the SVN commit message -->
-    <property name="commit.message" value="Utilsplugin2: added pasting tags from text clipboard"/>
+    <property name="commit.message" value="Utilsplugin2: improved pasting tags: paste from JOSM, support JSON format"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
     <property name="plugin.main.version" value="4980"/>
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteTagsExtendedAction.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteTagsExtendedAction.java	(revision 29226)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteTagsExtendedAction.java	(revision 29234)
@@ -6,6 +6,8 @@
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.actions.PasteTagsAction;
 import org.openstreetmap.josm.command.ChangePropertyCommand;
 import org.openstreetmap.josm.command.Command;
@@ -24,5 +26,5 @@
         super(tr("Paste tags [testing]"), "pastetags", tr("Apply tags parsed from buffer to all selected items.."),
             Shortcut.registerShortcut("tools:pastetags", tr("Tool: {0}", tr("Paste tags")),
-            KeyEvent.VK_T, Shortcut.CTRL), true); // TODO: shortcut is temporary, will be on Ctrl-Shift-V
+            KeyEvent.VK_T, Shortcut.CTRL), true, "textpastetags", false); // TODO: shortcut is temporary, will be on Ctrl-Shift-V
         //putValue("help", ht("/Action/Paste"));
     }
@@ -39,8 +41,18 @@
         String buf = Utils.getClipboardContent();
 
-        if (buf==null) return;
         List<Command> commands = new ArrayList<Command>();
-        for (Tag tag: TextTagParser.readTagsFromText(buf)) {
-            commands.add(new ChangePropertyCommand(selection, tag.getKey(), "".equals(tag.getValue())?null:tag.getValue()));
+        if (buf==null || buf.matches("(\\d+,)*\\d+")) { // Paste tags from JOSM buffer
+            PasteTagsAction.TagPaster tagPaster = new PasteTagsAction.TagPaster(Main.pasteBuffer.getDirectlyAdded(), selection);
+            for (Tag tag: tagPaster.execute()) {
+                commands.add(new ChangePropertyCommand(selection, tag.getKey(), "".equals(tag.getValue())?null:tag.getValue()));
+            }
+        } else { // Paste tags from arbitrary text
+            Map<String, String> tags = TextTagParser.readTagsFromText(buf);
+            if (tags==null) return;
+            String v;
+            for (String key: tags.keySet()) {
+                v = tags.get(key);
+                commands.add(new ChangePropertyCommand(selection, key, "".equals(v)?null:v));
+            }
         }
         if (!commands.isEmpty()) {
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/URLList.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/URLList.java	(revision 29226)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/URLList.java	(revision 29234)
@@ -28,10 +28,8 @@
         items.add("Wikipedia RU");
         items.add(defaultURL);
-        items.add("LatLon buildings");
-        items.add("http://latlon.org/buildings?zoom=17&lat={#lat}&lon={#lon}&layers=B");
-        items.add("AMDMi3 Russian streets");
-        items.add("http://addresses.amdmi3.ru/?zoom=11&lat={#lat}&lon={#lon}&layers=B00");
-        items.add("Mapki - More  History with CT");
-        items.add("http://osm.mapki.com/history/{#type}.php?id={#id}");
+        items.add("Who Dit It?");
+        items.add("http://simon04.dev.openstreetmap.org/whodidit/?zoom=12&lat={#lat}&lon={#lat}&layers=BTT");
+        items.add("Keep Right validator");
+        items.add("http://keepright.ipax.at/report_map.php?zoom=14&lat={#lat}&lon={#lat}&layers=B0T");
         items.add("Element history [demo, =Ctrl-Shift-H]");
         items.add("http://www.openstreetmap.org/browse/{#type}/{#id}/history");
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/helper/TextTagParser.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/helper/TextTagParser.java	(revision 29226)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/helper/TextTagParser.java	(revision 29234)
@@ -1,10 +1,8 @@
 package org.openstreetmap.josm.plugins.utilsplugin2.helper;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import org.openstreetmap.josm.data.osm.Tag;
 
 public class TextTagParser {
@@ -26,38 +24,11 @@
     }
     
-    /**
-     * Read tags from format, tag1\t val1 \n tag2 \t vat2 
-     * if possible
-     */
-    Collection<Tag> getFormattedTags() {
-         String lines[] = data.split("\n");
-         
-         Pattern p = Pattern.compile("(.*?)\t(.*?)");
-         List<Tag> tags = new ArrayList<Tag>();
-         String k=null, v=null;
-         for (String  line: lines) {
-            if (line.trim().isEmpty()) continue; // skiip empty lines
-            Matcher m = p.matcher(line);
-            if (m.matches()) {
-                 k=m.group(1).trim(); v=m.group(2).trim();
-                 tags.add(new Tag(k,v));
-            } else {
-                tags.clear();
-                break;
-            }
-         }
-         if (!tags.isEmpty()) {
-            return tags;
-        }  else {
-            return null;
-        }
-    }
-
+    
     /**
      * Read tags from "Free format"
      */
-    Collection<Tag> getParsedTags() {
+    Map<String, String>  getFreeParsedTags() {
         String k, v;
-        List<Tag> tags = new ArrayList<Tag>();
+        Map<String, String> tags = new HashMap<String,String>();
 
         while (true) {
@@ -77,5 +48,5 @@
             }
             v = parseString(false);
-            tags.add(new Tag(k, v));
+            tags.put(k, v);
         }
         return tags;
@@ -146,11 +117,80 @@
     }
 
-    public static Collection<Tag> readTagsFromText(String buf) {
+    private static String unescape(String k) {
+        if(! (k.startsWith("\"") && k.endsWith("\"")) ) {
+            if (k.contains("=")) {
+                // '=' not in quotes will be treated as an error!
+                return null;
+            } else {
+                return k;
+            }
+        }
+        String text = k.substring(1,k.length()-1);
+        return (new TextTagParser(text)).parseString(false);
+    }
+
+    /**
+     * Try to find tag-value pairs in given  @param text
+     * @param splitRegex - text is splitted into parts with this delimiter
+     * @param tagRegex - each part is matched against this regex
+     * @param unescapeTextInQuotes - if true, matched tag and value will be analyzed more thoroughly
+     */
+    public static Map<String, String> readTagsByRegexp(String text, String splitRegex, String tagRegex, boolean unescapeTextInQuotes) {
+         String lines[] = text.split(splitRegex);
+         Pattern p = Pattern.compile(tagRegex);
+         Map<String, String> tags = new HashMap<String,String>();
+         String k=null, v=null;
+         for (String  line: lines) {
+            if (line.trim().isEmpty()) continue; // skiip empty lines
+            Matcher m = p.matcher(line);
+            if (m.matches()) {
+                 k=m.group(1).trim(); v=m.group(2).trim();
+                 if (unescapeTextInQuotes) {
+                     k = unescape(k);
+                     v = unescape(v);
+                     if (k==null || v==null) return null;
+                 } 
+                 tags.put(k,v);
+            } else {
+                return null;
+            }
+         }
+         if (!tags.isEmpty()) {
+            return tags;
+         }  else {
+            return null;
+         }    
+    }
+ 
+    public static Map<String,String> readTagsFromText(String buf) {
+        Map<String,String> tags;
+        
+        // Format
+        // tag1\tval1\ntag2\tval2\n
+        tags = readTagsByRegexp(buf, "[\r\n]+]", "(.*?)\t(.*?)", false);
+                // try "tag\tvalue\n" format
+        if (tags!=null) return tags;
+
+        // Format
+        // a=b \n c=d \n "a b"=hello 
+        // SORRY: "a=b" = c is not supported fror now, only first = will be considered
+        // a = "b=c" is OK
+        // a = b=c  - this method of parsing fails intentionally
+        tags = readTagsByRegexp(buf, "[\\n\\t\\r]+", "(.*?)=(.*?)", true);
+                // try format  t1=v1\n t2=v2\n ...
+        if (tags!=null) return tags;
+        
+        // JSON-format
+        String bufJson = buf.trim();
+        if (bufJson.startsWith("{") && bufJson.endsWith("}") ) bufJson = bufJson.substring(1,bufJson.length()-1);
+        tags = readTagsByRegexp(bufJson, "[\\s]*,[\\s]*", 
+                "[\\s]*(\\\".*?[^\\\\]\\\")"+"[\\s]*:[\\s]*"+"(\\\".*?[^\\\\]\\\")[\\s]*", true);
+        if (tags!=null) return tags;
+
+        // Free format 
+        // a 1 "b" 2 c=3 d 4 e "5"
         TextTagParser parser = new TextTagParser(buf);
-        Collection<Tag> tags;
-        tags = parser.getFormattedTags(); // try "tag\tvalue\n" format
-        if (tags == null) {
-            tags = parser.getParsedTags();
-        }
+        System.out.println("free");
+        tags = parser.getFreeParsedTags();
         return tags;
 
