code: @Transient
      public ArrayList<Category> getFilterTagCategories() {
          final ArrayList<Category> categories = new ArrayList<Category>();
  
          for (final FilterTag filterTag : filterTags) {
              final int filterTagState = filterTag.getTagState();
  
              if (filterTagState == CommonFilterConstants.MATCH_TAG_STATE || filterTagState == CommonFilterConstants.NOT_MATCH_TAG_STATE) {
                  final Tag tag = filterTag.getTag();
                  final Set<TagToCategory> tagToCategories = tag.getTagToCategories();
  
                  if (tagToCategories.size() != 0) {
                      for (final TagToCategory category : tagToCategories) {
                          if (!categories.contains(category.getCategory())) {
                              categories.add(category.getCategory());
                          }
                      }
                  } else {
                      if (!categories.contains(null)) categories.add(null);
                  }
              }
          }
  
          return categories;
      }
docs: Not all FilterTags assigned to a filter have an associated FilterCategory. If a FilterTags belongs to a category that
  does not have an associated FilterCategory, the default boolean logic is used.
  <p/>
  This function returns all the categories that the tags in this filter belong to. These are then matched to any associated
  FilterCategories to find out how the tags are matched (i.e. are we matching all the tags ("And" logic), or one or more of
  the tags matches ("Or" logic)), using the default logic ("Or") if no associated FilterCategory exists.
  
  @return An ArrayList containing the Category IDs that the tags in this filter belong to