@Override
  public CloseableIterator<FileGroup> getFiles(Query query) {
    // normally the different type names are actually sharing the same files, but we cannot be
    // sure, a manually setup mosaic could indeed have multiple types with different files in
    // them...
    SimpleFeatureCollection fc = null;
    try {
      Query updatedQuery = query != null ? query : new Query();
      Filter filter = updatedQuery.getFilter();

      // TODO: Improve this check since it may contain multiple filters
      if (!"location".equalsIgnoreCase(locationAttributeName) && filter instanceof LikeFilterImpl) {
        // Rewrap the filter to update the file search
        LikeFilterImpl likeFilter = (LikeFilterImpl) filter;
        AttributeExpressionImpl impl = (AttributeExpressionImpl) likeFilter.getExpression();
        String attribute = impl.getPropertyName();
        String value = likeFilter.getLiteral();
        if ("location".equalsIgnoreCase(attribute)) {
          // The invoker provided a default "location" attribute.
          // make sure to remap it to the actual location attribute
          attribute = locationAttributeName;
          updatedQuery.setFilter(FF.like(FF.property(attribute), value));
        }
      }
      final List<SortBy> clauses = new ArrayList<SortBy>(1);
      clauses.add(
          new SortByImpl(
              FeatureUtilities.DEFAULT_FILTER_FACTORY.property(locationAttributeName),
              SortOrder.ASCENDING));
      final SortBy[] sb = clauses.toArray(new SortBy[] {});
      final boolean isSortBySupported =
          granuleCatalog.getQueryCapabilities(typeName).supportsSorting(sb);
      if (isSortBySupported) {
        updatedQuery.setSortBy(sb);
      }
      updatedQuery.setTypeName(typeName);

      // TODO: Make sure to add different iterator for stores
      // not supporting sortBy (which DB based stores don't support sorting?)

      // Get all the features matching the query
      fc = granuleCatalog.getGranules(updatedQuery);
      return new CloseableFileGroupIterator(fc.features());
    } catch (IOException ioe) {
      throw new RuntimeException(ioe);
    }
  }
  /** PropertyIsLike filter maps to a Contextual search criteria. */
  @Override
  public Object visit(PropertyIsLike filter, Object data) {
    logger.debug("ENTERING: PropertyIsLike filter");

    LikeFilterImpl likeFilter = (LikeFilterImpl) filter;

    AttributeExpressionImpl expression = (AttributeExpressionImpl) likeFilter.getExpression();
    String selectors = expression.getPropertyName();
    logger.debug("selectors = " + selectors);

    String searchPhrase = likeFilter.getLiteral();
    logger.debug("searchPhrase = [" + searchPhrase + "]");
    if (contextualSearch != null) {
      contextualSearch.setSearchPhrase(
          contextualSearch.getSearchPhrase() + " " + curNest.toString() + " " + searchPhrase);
    } else {
      contextualSearch = new ContextualSearch(selectors, searchPhrase, likeFilter.isMatchingCase());
    }

    logger.debug("EXITING: PropertyIsLike filter");

    return super.visit(filter, data);
  }