+ List<String> featureGroups = fr.getFeatureGroups();
+
+ /*
+ * sort groups alphabetically, and ensure that features with a
+ * null or empty group are output after those in named groups
+ */
+ List<String> sortedGroups = new ArrayList<>(featureGroups);
+ sortedGroups.remove(null);
+ sortedGroups.remove("");
+ Collections.sort(sortedGroups);
+ sortedGroups.add(null);
+ sortedGroups.add("");
+
+ int count = 0;
+ List<String> visibleGroups = fr.getDisplayedFeatureGroups();
+
+ /*
+ * loop over all groups (may be visible or not);
+ * non-positional features are output even if group is not visible
+ */
+ for (String group : sortedGroups)