Index: /applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikipediaToggleDialog.java
===================================================================
--- /applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikipediaToggleDialog.java	(revision 28469)
+++ /applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikipediaToggleDialog.java	(revision 28470)
@@ -16,6 +16,6 @@
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -53,4 +53,5 @@
 import org.openstreetmap.josm.tools.LanguageInfo;
 import org.openstreetmap.josm.tools.OpenBrowser;
+import org.openstreetmap.josm.tools.Utils;
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
@@ -94,6 +95,13 @@
                 public JLabel getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                     JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
-                    if (articles.contains(((WikipediaEntry) value).name)) {
+                    final WikipediaEntry entry = (WikipediaEntry) value;
+                    if (entry.getWiwosmStatus() != null && entry.getWiwosmStatus()) {
+                        label.setIcon(ImageProvider.getIfAvailable("misc", "grey_check"));
+                        label.setToolTipText(tr("Available via WIWOSM server"));
+                    } else if (articles.contains(entry.wikipediaArticle)) {
                         label.setIcon(ImageProvider.getIfAvailable("misc", "green_check"));
+                        label.setToolTipText(tr("Available in local dataset"));
+                    } else {
+                        label.setToolTipText(tr("Not linked yet"));
                     }
                     return label;
@@ -107,8 +115,9 @@
             if (index >= 0) {
                 final String description = ((WikipediaEntry) model.getElementAt(index)).description;
-                return description == null ? null : ("<html>" + description + "</html>");
-            } else {
-                return null;
-            }
+                if (description != null) {
+                    return "<html>" + description + "</html>";
+                }
+            }
+            return super.getToolTipText(e);
         }
     };
@@ -128,9 +137,5 @@
             }
             // decode URL for nicer value
-            try {
-                url = URLDecoder.decode(url, "UTF-8");
-            } catch (UnsupportedEncodingException ex) {
-                throw new IllegalStateException(ex);
-            }
+            url = decodeURL(url);
             // extract Wikipedia language and
             final Matcher m = Pattern.compile("https?://(\\w*)\\.wikipedia\\.org/wiki/(.*)").matcher(url);
@@ -147,4 +152,5 @@
         final String wikipediaLang, wikipediaArticle;
         final LatLon coordinate;
+        private Boolean wiwosmStatus;
 
         public WikipediaEntry(String name, String description, LatLon coordinate) {
@@ -170,4 +176,7 @@
 
         protected final String getHrefFromDescription() {
+            if (description == null) {
+                return null;
+            }
             final Matcher m = Pattern.compile(".*href=\"(.+?)\".*").matcher(description);
             if (m.matches()) {
@@ -183,4 +192,25 @@
         }
 
+        private void updateWiwosmStatus() {
+            try {
+                final String url = "http://toolserver.org/~master/osmjson/getGeoJSON.php?action=check"
+                        + "&lang=" + wikipediaLang
+                        + "&article=" + encodeURL(wikipediaArticle);
+                System.out.println("Wikipedia: GET " + url);
+                final Scanner scanner = new Scanner(new URL(url).openStream());
+                wiwosmStatus = scanner.hasNextInt() && scanner.nextInt() == 1;
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        public void setWiwosmStatus(Boolean wiwosmStatus) {
+            this.wiwosmStatus = wiwosmStatus;
+        }
+
+        public Boolean getWiwosmStatus() {
+            return wiwosmStatus;
+        }
+
         @Override
         public String toString() {
@@ -191,4 +221,38 @@
         public int compareTo(WikipediaEntry o) {
             return name.compareTo(o.name);
+        }
+    }
+
+    private void setWikipediaEntries(Collection<WikipediaEntry> entries) {
+        Collection<String> articleNames = new ArrayList<String>();
+        for (WikipediaEntry i : entries) {
+            articleNames.add(i.wikipediaArticle);
+        }
+        final String url = "https://toolserver.org/~simon04/getGeoJSONStatus.php"
+                + "?lang=" + wikipediaLang.get()
+                + "&articles=" + encodeURL(Utils.join(",", articleNames));
+        System.out.println("Wikipedia: GET " + url);
+        Map<String, Boolean> status = new HashMap<String, Boolean>();
+
+        try {
+            final Scanner scanner = new Scanner(new URL(url).openStream()).useDelimiter("\n");
+            while (scanner.hasNext()) {
+                //[article]\t[0|1]
+                final String line = scanner.next();
+                final String[] x = line.split("\t");
+                if (x.length == 2) {
+                    status.put(x[0], "1".equals(x[1]));
+                } else {
+                    System.err.println("Unknown element "+line);
+                }
+            }
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+
+        model.clear();
+        for (WikipediaEntry i : entries) {
+            i.setWiwosmStatus(status.get(i.wikipediaArticle));
+            model.addElement(i);
         }
     }
@@ -220,5 +284,5 @@
                 NodeList nodes = (NodeList) xpathPlacemark.evaluate(doc, XPathConstants.NODESET);
                 // construct WikipediaEntry for each XML element
-                List<WikipediaEntry> entries = new LinkedList<WikipediaEntry>();
+                List<WikipediaEntry> entries = new ArrayList<WikipediaEntry>(nodes.getLength());
                 for (int i = 0; i < nodes.getLength(); i++) {
                     final String[] coord = xpathCoord.evaluate(nodes.item(i)).split(",");
@@ -233,8 +297,5 @@
                 Collections.sort(entries);
                 // add entries to list model
-                model.clear();
-                for (WikipediaEntry i : entries) {
-                    model.addElement(i);
-                }
+                setWikipediaEntries(entries);
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
@@ -259,15 +320,15 @@
                         + "wikilang=" + wikipediaLang.get()
                         + "&wikifam=.wikipedia.org"
-                        + "&basecat=" + URLEncoder.encode(category, "UTF-8")
+                        + "&basecat=" + encodeURL(category)
                         + "&basedeep=3&templates=&mode=al&format=csv";
                 System.out.println("Wikipedia: GET " + url);
                 final Scanner scanner = new Scanner(new URL(url).openStream()).useDelimiter("\n");
-                if (scanner.hasNext()) {
-                    model.clear();
-                }
+                final List<WikipediaEntry> entries = new ArrayList<WikipediaEntry>();
                 while (scanner.hasNext()) {
                     final String article = scanner.next().split("\t")[1].replace("_", " ");
-                    model.addElement(new WikipediaEntry(article, wikipediaLang.get(), article));
-                }
+                    entries.add(new WikipediaEntry(article, wikipediaLang.get(), article));
+                }
+                Collections.sort(entries);
+                setWikipediaEntries(entries);
             } catch (IOException ex) {
                 throw new RuntimeException(ex);
@@ -291,5 +352,6 @@
                     url = entry.getHrefFromDescription();
                 } else {
-                    url = "http://" + entry.wikipediaLang + ".wikipedia.org/wiki/" + entry.wikipediaArticle.replace(" ", "_");
+                    url = "http://" + entry.wikipediaLang + ".wikipedia.org/wiki/"
+                            + encodeURL(entry.wikipediaArticle.replace(" ", "_"));
                 }
                 System.out.println("Wikipedia: opening " + url);
@@ -362,11 +424,7 @@
         } else if (wp != null) {
             //wikipedia=[lang]:[article]
-            try {
-                String[] item = URLDecoder.decode(wp, "UTF-8").split(":", 2);
-                if (item.length == 2 && wikipediaLang.get().equals(item[0])) {
-                    r.add(item[1].replace("_", " "));
-                }
-            } catch (UnsupportedEncodingException ex) {
-                throw new IllegalStateException(ex);
+            String[] item = decodeURL(wp).split(":", 2);
+            if (item.length == 2 && wikipediaLang.get().equals(item[0])) {
+                r.add(item[1].replace("_", " "));
             }
         }
@@ -382,10 +440,6 @@
             //wikipedia:[lang]=[lang]:[article]
             //wikipedia:[lang]=[article]
-            try {
-                String[] item = URLDecoder.decode(wpLang, "UTF-8").split(":", 2);
-                r.add(item[item.length == 2 ? 1 : 0].replace("_", " "));
-            } catch (UnsupportedEncodingException ex) {
-                throw new IllegalStateException(ex);
-            }
+            String[] item = decodeURL(wpLang).split(":", 2);
+            r.add(item[item.length == 2 ? 1 : 0].replace("_", " "));
         }
         return r;
@@ -419,3 +473,19 @@
         list.repaint();
     }
+
+    public static String decodeURL(String url) {
+        try {
+            return URLDecoder.decode(url, "UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    public static String encodeURL(String url) {
+        try {
+            return URLEncoder.encode(url, "UTF-8");
+        } catch (UnsupportedEncodingException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
 }
