+ String[] types = visibleColours == null ? new String[0]
+ : visibleColours.keySet()
+ .toArray(new String[visibleColours.keySet().size()]);
+
+ /*
+ * feature filters if any
+ */
+ outputFeatureFilters(out, visibleColours, featureFilters);
+
+ /*
+ * output features within groups
+ */
+ int count = outputFeaturesByGroup(out, fr, types, sequences,
+ includeNonPositional);
+
+ return count > 0 ? out.toString() : "No Features Visible";
+ }
+
+ /**
+ * Outputs any feature filters defined for visible feature types, sandwiched by
+ * STARTFILTERS and ENDFILTERS lines
+ *
+ * @param out
+ * @param visible
+ * @param featureFilters
+ */
+ void outputFeatureFilters(StringBuilder out,
+ Map<String, FeatureColourI> visible,
+ Map<String, FeatureMatcherSetI> featureFilters)
+ {
+ if (visible == null || featureFilters == null
+ || featureFilters.isEmpty())
+ {
+ return;
+ }
+
+ boolean first = true;
+ for (String featureType : visible.keySet())
+ {
+ FeatureMatcherSetI filter = featureFilters.get(featureType);
+ if (filter != null)
+ {
+ if (first)
+ {
+ first = false;
+ out.append(newline).append(STARTFILTERS).append(newline);
+ }
+ out.append(featureType).append(TAB).append(filter.toStableString())
+ .append(newline);
+ }
+ }
+ if (!first)
+ {
+ out.append(ENDFILTERS).append(newline);
+ }
+
+ }
+
+ /**
+ * Appends output of visible sequence features within feature groups to the
+ * output buffer. Groups other than the null or empty group are sandwiched by
+ * STARTGROUP and ENDGROUP lines. Answers the number of features written.
+ *
+ * @param out
+ * @param fr
+ * @param featureTypes
+ * @param sequences
+ * @param includeNonPositional
+ * @return
+ */
+ private int outputFeaturesByGroup(StringBuilder out,
+ FeatureRenderer fr, String[] featureTypes,
+ SequenceI[] sequences, boolean includeNonPositional)
+ {
+ List<String> featureGroups = fr.getFeatureGroups();