Index: trunk/scripts/SyncEditorLayerIndex.java
===================================================================
--- trunk/scripts/SyncEditorLayerIndex.java	(revision 15658)
+++ trunk/scripts/SyncEditorLayerIndex.java	(revision 15692)
@@ -31,4 +31,5 @@
 import java.util.Objects;
 import java.util.Set;
+import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.regex.Matcher;
@@ -56,4 +57,5 @@
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OptionParser;
@@ -257,7 +259,11 @@
     }
 
-    void myprintlnfinal(String s) throws IOException {
+    void myprintlnfinal(String s) {
         if (outputStream != null) {
-            outputStream.write(s + System.getProperty("line.separator"));
+            try {
+                outputStream.write(s + System.getProperty("line.separator"));
+            } catch (IOException e) {
+                throw new JosmRuntimeException(e);
+            }
         } else {
             System.out.println(s);
@@ -265,5 +271,5 @@
     }
 
-    void myprintln(String s) throws IOException {
+    void myprintln(String s) {
         if (skip.containsKey(s)) {
             String color = skip.get(s);
@@ -290,5 +296,5 @@
     }
 
-    void start() throws IOException {
+    void start() {
         if (optionXhtml) {
             myprintlnfinal(
@@ -300,5 +306,5 @@
     }
 
-    void end() throws IOException {
+    void end() {
         for (String s : skip.keySet()) {
             myprintln("+++ Obsolete skip entry: " + s);
@@ -504,5 +510,5 @@
     }
 
-    void checkInOneButNotTheOther() throws IOException {
+    void checkInOneButNotTheOther() {
         List<String> le = new LinkedList<>(eliUrls.keySet());
         List<String> lj = new LinkedList<>(josmUrls.keySet());
@@ -564,5 +570,5 @@
     }
 
-    void checkCommonEntries() throws IOException {
+    void checkCommonEntries() {
         doSameUrlButDifferentName();
         doSameUrlButDifferentId();
@@ -575,8 +581,9 @@
         doMismatchingShapes();
         doMismatchingIcons();
+        doMismatchingCategories();
         doMiscellaneousChecks();
     }
 
-    void doSameUrlButDifferentName() throws IOException {
+    void doSameUrlButDifferentName() {
         myprintln("*** Same URL, but different name: ***");
         for (String url : eliUrls.keySet()) {
@@ -592,5 +599,5 @@
     }
 
-    void doSameUrlButDifferentId() throws IOException {
+    void doSameUrlButDifferentId() {
         myprintln("*** Same URL, but different Id: ***");
         for (String url : eliUrls.keySet()) {
@@ -606,5 +613,5 @@
     }
 
-    void doSameUrlButDifferentType() throws IOException {
+    void doSameUrlButDifferentType() {
         myprintln("*** Same URL, but different type: ***");
         for (String url : eliUrls.keySet()) {
@@ -618,5 +625,5 @@
     }
 
-    void doSameUrlButDifferentZoomBounds() throws IOException {
+    void doSameUrlButDifferentZoomBounds() {
         myprintln("*** Same URL, but different zoom bounds: ***");
         for (String url : eliUrls.keySet()) {
@@ -644,5 +651,5 @@
     }
 
-    void doSameUrlButDifferentCountryCode() throws IOException {
+    void doSameUrlButDifferentCountryCode() {
         myprintln("*** Same URL, but different country code: ***");
         for (String url : eliUrls.keySet()) {
@@ -660,5 +667,5 @@
     }
 
-    void doSameUrlButDifferentQuality() throws IOException {
+    void doSameUrlButDifferentQuality() {
         myprintln("*** Same URL, but different quality: ***");
         for (String url : eliUrls.keySet()) {
@@ -678,5 +685,5 @@
     }
 
-    void doSameUrlButDifferentDates() throws IOException {
+    void doSameUrlButDifferentDates() {
         myprintln("*** Same URL, but different dates: ***");
         Pattern pattern = Pattern.compile("^(.*;)(\\d\\d\\d\\d)(-(\\d\\d)(-(\\d\\d))?)?$");
@@ -720,5 +727,5 @@
     }
 
-    void doSameUrlButDifferentInformation() throws IOException {
+    void doSameUrlButDifferentInformation() {
         myprintln("*** Same URL, but different information: ***");
         for (String url : eliUrls.keySet()) {
@@ -738,5 +745,5 @@
     }
 
-    void compareDescriptions(JsonObject e, ImageryInfo j) throws IOException {
+    void compareDescriptions(JsonObject e, ImageryInfo j) {
         String et = getDescriptions(e).getOrDefault("en", "");
         String jt = getDescriptions(j).getOrDefault("en", "");
@@ -752,5 +759,5 @@
     }
 
-    void comparePermissionReferenceUrls(JsonObject e, ImageryInfo j) throws IOException {
+    void comparePermissionReferenceUrls(JsonObject e, ImageryInfo j) {
         String et = getPermissionReferenceUrl(e);
         String jt = getPermissionReferenceUrl(j);
@@ -780,5 +787,5 @@
     }
 
-    void compareAttributionUrls(JsonObject e, ImageryInfo j) throws IOException {
+    void compareAttributionUrls(JsonObject e, ImageryInfo j) {
         String et = getAttributionUrl(e);
         String jt = getAttributionUrl(j);
@@ -799,5 +806,5 @@
     }
 
-    void compareAttributionTexts(JsonObject e, ImageryInfo j) throws IOException {
+    void compareAttributionTexts(JsonObject e, ImageryInfo j) {
         String et = getAttributionText(e);
         String jt = getAttributionText(j);
@@ -813,5 +820,5 @@
     }
 
-    void compareProjections(JsonObject e, ImageryInfo j) throws IOException {
+    void compareProjections(JsonObject e, ImageryInfo j) {
         String et = getProjections(e).stream().sorted().collect(Collectors.joining(" "));
         String jt = getProjections(j).stream().sorted().collect(Collectors.joining(" "));
@@ -836,5 +843,5 @@
     }
 
-    void compareDefaults(JsonObject e, ImageryInfo j) throws IOException {
+    void compareDefaults(JsonObject e, ImageryInfo j) {
         boolean ed = getDefault(e);
         boolean jd = getDefault(j);
@@ -848,5 +855,5 @@
     }
 
-    void compareOverlays(JsonObject e, ImageryInfo j) throws IOException {
+    void compareOverlays(JsonObject e, ImageryInfo j) {
         boolean eo = getOverlay(e);
         boolean jo = getOverlay(j);
@@ -860,5 +867,5 @@
     }
 
-    void compareNoTileHeaders(JsonObject e, ImageryInfo j) throws IOException {
+    void compareNoTileHeaders(JsonObject e, ImageryInfo j) {
         Map<String, Set<String>> eh = getNoTileHeader(e);
         Map<String, Set<String>> jh = getNoTileHeader(j);
@@ -874,5 +881,5 @@
     }
 
-    void doMismatchingShapes() throws IOException {
+    void doMismatchingShapes() {
         myprintln("*** Mismatching shapes: ***");
         for (String url : josmUrls.keySet()) {
@@ -998,37 +1005,63 @@
     }
 
-    void doMismatchingIcons() throws IOException {
+    void doMismatchingIcons() {
         myprintln("*** Mismatching icons: ***");
+        doMismatching(this::compareIcons);
+    }
+
+    void doMismatchingCategories() {
+        myprintln("*** Mismatching categories: ***");
+        doMismatching(this::compareCategories);
+    }
+
+    void doMismatching(BiConsumer<ImageryInfo, JsonObject> comparator) {
         for (String url : eliUrls.keySet()) {
-            JsonObject e = eliUrls.get(url);
-            if (!josmUrls.containsKey(url)) {
-                continue;
-            }
-            ImageryInfo j = josmUrls.get(url);
-            String ij = getIcon(j);
-            String ie = getIcon(e);
-            boolean ijok = isNotBlank(ij);
-            boolean ieok = isNotBlank(ie);
-            if (ijok && !ieok) {
-                if (!optionNoEli) {
-                    myprintln("+ No ELI icon: "+getDescription(j));
-                }
-            } else if (!ijok && ieok) {
-                myprintln("- No JOSM icon: "+getDescription(j));
-            } else if (ijok && ieok && !Objects.equals(ij, ie) && !(
-              (ie.startsWith("https://osmlab.github.io/editor-layer-index/")
-              || ie.startsWith("https://raw.githubusercontent.com/osmlab/editor-layer-index/")) &&
-              ij.startsWith("data:"))) {
-                String iehttps = ie.replace("http:", "https:");
-                if (ij.equals(iehttps)) {
-                    myprintln("+ Different icons: "+getDescription(j));
-                } else {
-                    myprintln("* Different icons: "+getDescription(j));
-                }
-            }
-        }
-    }
-
-    void doMiscellaneousChecks() throws IOException {
+            if (josmUrls.containsKey(url)) {
+                comparator.accept(josmUrls.get(url), eliUrls.get(url));
+            }
+        }
+    }
+
+    void compareIcons(ImageryInfo j, JsonObject e) {
+        String ij = getIcon(j);
+        String ie = getIcon(e);
+        boolean ijok = isNotBlank(ij);
+        boolean ieok = isNotBlank(ie);
+        if (ijok && !ieok) {
+            if (!optionNoEli) {
+                myprintln("+ No ELI icon: "+getDescription(j));
+            }
+        } else if (!ijok && ieok) {
+            myprintln("- No JOSM icon: "+getDescription(j));
+        } else if (ijok && ieok && !Objects.equals(ij, ie) && !(
+          (ie.startsWith("https://osmlab.github.io/editor-layer-index/")
+          || ie.startsWith("https://raw.githubusercontent.com/osmlab/editor-layer-index/")) &&
+          ij.startsWith("data:"))) {
+            String iehttps = ie.replace("http:", "https:");
+            if (ij.equals(iehttps)) {
+                myprintln("+ Different icons: "+getDescription(j));
+            } else {
+                myprintln("* Different icons: "+getDescription(j));
+            }
+        }
+    }
+
+    void compareCategories(ImageryInfo j, JsonObject e) {
+        String cj = getCategory(j);
+        String ce = getCategory(e);
+        boolean cjok = isNotBlank(cj);
+        boolean ceok = isNotBlank(ce);
+        if (cjok && !ceok) {
+            if (!optionNoEli) {
+                myprintln("+ No ELI category: "+getDescription(j));
+            }
+        } else if (!cjok && ceok) {
+            myprintln("- No JOSM category: "+getDescription(j));
+        } else if (cjok && ceok && !Objects.equals(cj, ce)) {
+            myprintln("+ Different categories: "+getDescription(j));
+        }
+    }
+
+    void doMiscellaneousChecks() {
         myprintln("*** Miscellaneous checks: ***");
         Map<String, ImageryInfo> josmIds = new HashMap<>();
@@ -1376,5 +1409,5 @@
             return ((ImageryInfo) e).getImageryCategoryOriginalString();
         }
-        return null;
+        return ((Map<String, JsonObject>) e).get("properties").getString("category", null);
     }
 
Index: trunk/scripts/TagInfoExtract.java
===================================================================
--- trunk/scripts/TagInfoExtract.java	(revision 15658)
+++ trunk/scripts/TagInfoExtract.java	(revision 15692)
@@ -128,4 +128,5 @@
     /**
      * Parse command line arguments.
+     * @param args command line arguments
      */
     private void parseCommandLineArguments(String[] args) {
@@ -203,4 +204,5 @@
          * Determine full image url (can refer to JOSM or OSM repository).
          * @param path the image path
+         * @return full image url
          */
         private String findImageUrl(String path) {
@@ -323,4 +325,6 @@
         /**
          * Read the style sheet file and parse the MapCSS code.
+         * @throws IOException if any I/O error occurs
+         * @throws ParseException in case of parsing error
          */
         private void parseStyleSheet() throws IOException, ParseException {
@@ -335,4 +339,5 @@
         /**
          * Collect all the tag from the style sheet.
+         * @return list of taginfo tags
          */
         private List<TagInfoTag> convertStyleSheet() {
@@ -403,4 +408,7 @@
             /**
              * Create image file from StyleElement.
+             * @param element style element
+             * @param type object type
+             * @param nc navigatable component
              *
              * @return the URL
@@ -428,4 +436,5 @@
              * @param generateImage if true, create or find a suitable image icon and return URL,
              *                       if false, just check if tag is supported and return true or false
+             * @return URL for image icon if tag is supported
              */
             abstract Optional<String> findUrl(boolean generateImage);
@@ -550,4 +559,5 @@
     /**
      * Initialize the script.
+     * @throws IOException if any I/O error occurs
      */
     private void init() throws IOException {
