Index: trunk/scripts/TagInfoExtract.java
===================================================================
--- trunk/scripts/TagInfoExtract.java	(revision 17976)
+++ trunk/scripts/TagInfoExtract.java	(revision 17977)
@@ -1,4 +1,3 @@
 // License: GPL. For details, see LICENSE file.
-
 import java.awt.Graphics2D;
 import java.awt.image.BufferedImage;
@@ -249,5 +248,4 @@
             }
         }
-
     }
 
@@ -266,4 +264,5 @@
         List<TagInfoTag> convertPresets(Iterable<TaggingPreset> presets, String descriptionPrefix, boolean addImages) {
             final List<TagInfoTag> tags = new ArrayList<>();
+            final Map<Tag, TagInfoTag> requiredTags = new LinkedHashMap<>();
             final Map<Tag, TagInfoTag> optionalTags = new LinkedHashMap<>();
             for (TaggingPreset preset : presets) {
@@ -278,23 +277,29 @@
                                 Set<TagInfoTag.Type> types = TagInfoTag.Type.forPresetTypes(preset.types);
                                 if (item.isKeyRequired()) {
-                                    tags.add(new TagInfoTag(descriptionPrefix + preset.getName(), item.key, value, types,
-                                            addImages && preset.iconName != null ? options.findImageUrl(preset.iconName) : null));
+                                    fillTagsMap(requiredTags, item, value, preset.getName(), types,
+                                            descriptionPrefix + TagInfoTag.REQUIRED_FOR_COUNT + ": ",
+                                            addImages && preset.iconName != null ? options.findImageUrl(preset.iconName) : null);
                                 } else if (Presets.class.equals(getClass())) { // not for ExternalPresets
-                                    optionalTags.compute(new Tag(item.key, value), (osmTag, tagInfoTag) -> {
-                                        if (tagInfoTag == null) {
-                                            String description = descriptionPrefix + TagInfoTag.OPTIONAL_FOR_COUNT + ": " + preset.getName();
-                                            return new TagInfoTag(description, item.key, value, types, null);
-                                        } else {
-                                            tagInfoTag.descriptions.add(preset.getName());
-                                            tagInfoTag.objectTypes.addAll(types);
-                                            return tagInfoTag;
-                                        }
-                                    });
+                                    fillTagsMap(optionalTags, item, value, preset.getName(), types,
+                                            descriptionPrefix + TagInfoTag.OPTIONAL_FOR_COUNT + ": ", null);
                                 }
                             }
                         });
             }
+            tags.addAll(requiredTags.values());
             tags.addAll(optionalTags.values());
             return tags;
+        }
+
+        private void fillTagsMap(Map<Tag, TagInfoTag> optionalTags, KeyedItem item, String value, String presetName, Set<TagInfoTag.Type> types, String descriptionPrefix, String iconUrl) {
+            optionalTags.compute(new Tag(item.key, value), (osmTag, tagInfoTag) -> {
+                if (tagInfoTag == null) {
+                    return new TagInfoTag(descriptionPrefix + presetName, item.key, value, types, iconUrl);
+                } else {
+                    tagInfoTag.descriptions.add(presetName);
+                    tagInfoTag.objectTypes.addAll(types);
+                    return tagInfoTag;
+                }
+            });
         }
 
@@ -303,5 +308,4 @@
             return values.isEmpty() || values.size() > 50 ? Collections.singleton(null) : values;
         }
-
     }
 
@@ -328,5 +332,4 @@
                     Logging.warn(ex);
                 }
-
             }
             writeJson("JOSM user presets", "Tags supported by the user contributed presets in the OSM editor JOSM", tags);
@@ -491,5 +494,4 @@
                 return Optional.empty();
             }
-
         }
 
@@ -510,10 +512,8 @@
                 LineElement les = LineElement.createLine(env);
                 if (les != null) {
-                    if (!generateImage) return Optional.of("");
-                    return Optional.of(createImage(les, "way", nc));
+                    return Optional.of(generateImage ? createImage(les, "way", nc) : "");
                 }
                 return Optional.empty();
             }
-
         }
 
@@ -551,4 +551,5 @@
      */
     private static class TagInfoTag {
+        static final String REQUIRED_FOR_COUNT = "Required for {count}";
         static final String OPTIONAL_FOR_COUNT = "Optional for {count}";
         final Collection<String> descriptions = new ArrayList<>();
@@ -573,4 +574,5 @@
                 final int size = descriptions.size();
                 object.add("description", String.join(", ", Utils.limit(descriptions, 8, "..."))
+                        .replace(REQUIRED_FOR_COUNT, size > 3 ? "Required for " + size : "Required for")
                         .replace(OPTIONAL_FOR_COUNT, size > 3 ? "Optional for " + size : "Optional for"));
             }
@@ -605,8 +607,5 @@
 
             static Set<TagInfoTag.Type> forPresetTypes(Set<TaggingPresetType> types) {
-                if (types == null) {
-                    return Collections.emptySet();
-                }
-                return types.stream()
+                return types == null ? Collections.emptySet() : types.stream()
                         .map(Type::forPresetType)
                         .collect(Collectors.toCollection(() -> EnumSet.noneOf(Type.class)));
