+ }
+ return _gps;
+ }
+
+ /**
+ * Answers true if the feature belongs to a feature group which is not
+ * currently displayed, else false
+ *
+ * @param sequenceFeature
+ * @return
+ */
+ protected boolean featureGroupNotShown(final SequenceFeature sequenceFeature)
+ {
+ return featureGroups != null
+ && sequenceFeature.featureGroup != null
+ && sequenceFeature.featureGroup.length() != 0
+ && featureGroups.containsKey(sequenceFeature.featureGroup)
+ && !featureGroups.get(sequenceFeature.featureGroup)
+ .booleanValue();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<SequenceFeature> findFeaturesAtResidue(SequenceI sequence,
+ int resNo)
+ {
+ List<SequenceFeature> result = new ArrayList<>();
+ if (!av.areFeaturesDisplayed() || getFeaturesDisplayed() == null)
+ {
+ return result;
+ }
+
+ /*
+ * include features at the position provided their feature type is
+ * displayed, and feature group is null or the empty string
+ * or marked for display
+ */
+ Set<String> visibleFeatures = getFeaturesDisplayed()
+ .getVisibleFeatures();
+ String[] visibleTypes = visibleFeatures
+ .toArray(new String[visibleFeatures.size()]);
+ List<SequenceFeature> features = sequence.getFeatures().findFeatures(
+ resNo, resNo, visibleTypes);
+
+ for (SequenceFeature sf : features)
+ {
+ if (!featureGroupNotShown(sf))