Index: main/plugin-calendar/src/org/ametys/plugins/calendar/actions/SetFilterInRequestAttributesAction.java
===================================================================
--- main/plugin-calendar/src/org/ametys/plugins/calendar/actions/SetFilterInRequestAttributesAction.java	(revision 26702)
+++ main/plugin-calendar/src/org/ametys/plugins/calendar/actions/SetFilterInRequestAttributesAction.java	(working copy)
@@ -33,7 +33,7 @@
 import org.ametys.web.filter.WebContentFilter.AccessLimitation;
 import org.ametys.web.repository.page.Page;
 import org.ametys.web.repository.page.ZoneItem;
-import org.ametys.web.tags.TagCategory;
+import org.ametys.web.tags.Tag;
 
 /**
  * This action creates a filter for RSS calendar
@@ -50,7 +50,7 @@
     private String _view;
     private String _rangeType;
     private Set<String> _tags;
-    private Set<TagCategory> _categories;
+    private Set<Tag> _categories;
     private int _year;
     private int _month;
     private int _day;
Index: main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsFilter.java
===================================================================
--- main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsFilter.java	(revision 26702)
+++ main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsFilter.java	(working copy)
@@ -25,6 +25,7 @@
 import org.ametys.plugins.repository.query.expression.OrExpression;
 import org.ametys.web.repository.site.SiteManager;
 import org.ametys.web.tags.TagExpression;
+import org.ametys.web.tags.TagProviderExtensionPoint;
 
 /**
  * Content filter which allows to directly provide:
@@ -53,10 +54,11 @@
      * @param id The filter id
      * @param resolver The ametys object resolver
      * @param siteManager The site manager
+     * @param tagProviderEP 
      */
-    public EventsFilter(String id, AmetysObjectResolver resolver, SiteManager siteManager)
+    public EventsFilter(String id, AmetysObjectResolver resolver, SiteManager siteManager, TagProviderExtensionPoint tagProviderEP)
     {
-        super(id, resolver, siteManager);
+        super(id, resolver, siteManager, tagProviderEP);
         _orTags = new HashSet<String>();
     }
     
@@ -132,12 +134,13 @@
         
         /**
          * Get the expression corresponding to the filter's tags
+         * @param siteName The current site name
          * @return The expression corresponding to the filter's tags
          */
         @Override
-        public Expression getTagsExpression()
+        public Expression getTagsExpression(String siteName)
         {
-            Expression tagExpr = super.getTagsExpression();
+            Expression tagExpr = super.getTagsExpression(siteName);
             Expression expr = null;
             
             if (!_orTags.isEmpty())
Index: main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsFilterHelper.java
===================================================================
--- main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsFilterHelper.java	(revision 26702)
+++ main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsFilterHelper.java	(working copy)
@@ -43,7 +43,6 @@
 import org.ametys.web.filter.WebContentFilter.FilterSearchContext;
 import org.ametys.web.repository.page.ZoneItem;
 import org.ametys.web.tags.Tag;
-import org.ametys.web.tags.TagCategory;
 import org.ametys.web.tags.TagProviderExtensionPoint;
 
 /**
@@ -199,12 +198,13 @@
     public Set<String> getTags(ZoneItem zoneItem, String tagAsStr)
     {
         Set<String> tags = new LinkedHashSet<String>();
+        String internalTagAsStr = tagAsStr;
 
-        if (tagAsStr == null)
+        if (internalTagAsStr == null)
         {
-            tagAsStr = zoneItem.getServiceParameters().getString("tags", "");
+            internalTagAsStr = zoneItem.getServiceParameters().getString("tags", "");
         }
-        String[] tagsArray = StringUtils.isNotEmpty(tagAsStr) ? tagAsStr.split(",") : new String[0];
+        String[] tagsArray = StringUtils.isNotEmpty(internalTagAsStr) ? internalTagAsStr.split(",") : new String[0];
         for (int i = 0; i < tagsArray.length; i++)
         {
             tags.add(tagsArray[i]);
@@ -214,16 +214,17 @@
     }
 
     /**
-     * Get the selected tags categories.
+     * Get the selected tags to be used as categories.
      * 
      * @param zoneItem the zone item.
      * @param siteName the site name.
-     * @param categoriesAsStr the tag categories
+     * @param categories the tag categories as String.
      * @return the tags categories.
      */
-    public Set<TagCategory> getTagCategories(ZoneItem zoneItem, String siteName, String categoriesAsStr)
+    public Set<Tag> getTagCategories(ZoneItem zoneItem, String siteName, String categories)
     {
-        Set<TagCategory> categories = new LinkedHashSet<TagCategory>();
+        Set<Tag> results = new LinkedHashSet<Tag>();
+        String categoriesAsStr = categories;
 
         if (categoriesAsStr == null)
         {
@@ -233,70 +234,66 @@
         String[] categoriesArray = StringUtils.isNotEmpty(categoriesAsStr) ? categoriesAsStr.split(",") : new String[0];
         for (int i = 0; i < categoriesArray.length; i++)
         {
-            TagCategory category = _tagProviderEP.getCategory(siteName, categoriesArray[i]);
+            Tag category = _tagProviderEP.getTag(siteName, categoriesArray[i]);
             if (category != null)
             {
-                categories.add(category);
+                results.add(category);
             }
         }
 
-        return categories;
+        return results;
     }
 
     /**
-     * Get all the tags belonging to a collection of categories.
+     * Get all the descendant tags belonging to a collection of input tags.
      * 
-     * @param categories the collection of tag categories.
+     * @param tags the collection of input tag.
      * @return an exhaustive set of the tags.
      */
-    public Set<String> getAllTags(Collection<TagCategory> categories)
+    public Set<String> getAllTags(Collection<Tag> tags)
     {
         Set<String> allTags = new LinkedHashSet<String>();
 
-        for (TagCategory category : categories)
+        for (Tag tag : tags)
         {
-            Map<String, Tag> tags = category.getTags();
-            Map<String, TagCategory> subCategories = category.getCategories();
+            Map<String, Tag> childTagsMap = tag.getTags();
 
-            if (tags != null)
+            if (childTagsMap != null)
             {
-                for (Tag tag : tags.values())
+                Collection<Tag> childTags = childTagsMap.values();
+                for (Tag child : childTags)
                 {
-                    allTags.add(tag.getName());
+                    allTags.add(child.getName());
                 }
-            }
-            if (subCategories != null)
-            {
-                allTags.addAll(getAllTags(subCategories.values()));
+                
+                // recursive add.
+                allTags.addAll(getAllTags(childTags));
             }
         }
-
+        
         return allTags;
     }
 
     /**
-     * Get all the tags belonging to a single category.
+     * Get all the descendant tags belonging to a single tag.
      * 
-     * @param category the category.
+     * @param tag the tag.
      * @return an exhaustive set of the tags.
      */
-    protected Set<Tag> getAllTags(TagCategory category)
+    protected Set<Tag> getAllTags(Tag tag)
     {
         Set<Tag> allTags = new LinkedHashSet<Tag>();
 
-        Map<String, Tag> tags = category.getTags();
-        Map<String, TagCategory> subCategories = category.getCategories();
-
-        if (tags != null)
-        {
-            allTags.addAll(tags.values());
-        }
+        Map<String, Tag> childTagsMap = tag.getTags();
 
-        if (subCategories != null)
+        if (childTagsMap != null)
         {
-            for (TagCategory subCategory : subCategories.values())
+            Collection<Tag> childTags = childTagsMap.values();
+            allTags.addAll(childTags);
+            
+            for (Tag child : childTags)
             {
-                allTags.addAll(getAllTags(subCategory));
+                allTags.addAll(getAllTags(child));
             }
         }
 
Index: main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsGenerator.java
===================================================================
--- main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsGenerator.java	(revision 26702)
+++ main/plugin-calendar/src/org/ametys/plugins/calendar/events/EventsGenerator.java	(working copy)
@@ -57,7 +57,6 @@
 import org.ametys.web.repository.page.Page;
 import org.ametys.web.repository.page.ZoneItem;
 import org.ametys.web.tags.Tag;
-import org.ametys.web.tags.TagCategory;
 
 /**
  * Query and generate news according to many parameters.
@@ -151,7 +150,7 @@
         Set<String> tags = _eventsFilterHelper.getTags(zoneItem, parameters.getParameter("tags", null));
         // Get the categories of the tags to match, from the zone item or from
         // the parameters.
-        Set<TagCategory> categories = _eventsFilterHelper.getTagCategories(zoneItem, siteName, parameters.getParameter("tag-categories", null));
+        Set<Tag> categories = _eventsFilterHelper.getTagCategories(zoneItem, siteName, parameters.getParameter("tag-categories", null));
         // Get all tags belonging to the categories.
         Set<String> categoryTags = _eventsFilterHelper.getAllTags(categories);
         // Restrain the list to a single tag if provided.
@@ -573,15 +572,15 @@
     }
 
     /**
-     * Generate the list of selected categories and their tags.
+     * Generate the list of selected tags that act as categories and their descendant tags.
      * 
      * @param categories the list of categories to generate.
      * @throws SAXException
      */
-    protected void _saxCategories(Collection<TagCategory> categories) throws SAXException
+    protected void _saxCategories(Collection<Tag> categories) throws SAXException
     {
         XMLUtils.startElement(contentHandler, "tag-categories");
-        for (TagCategory category : categories)
+        for (Tag category : categories)
         {
             AttributesImpl categoryAttrs = new AttributesImpl();
 
Index: main/plugin-calendar/src/org/ametys/plugins/calendar/events/CalendarServiceCachePolicy.java
===================================================================
--- main/plugin-calendar/src/org/ametys/plugins/calendar/events/CalendarServiceCachePolicy.java	(revision 26702)
+++ main/plugin-calendar/src/org/ametys/plugins/calendar/events/CalendarServiceCachePolicy.java	(working copy)
@@ -54,7 +54,9 @@
                                  org.ametys.cms.observation.ObservationConstants.CONTENT_DELETED,
                                  ObservationConstants.CONTENT_TAGGED,
                                  ObservationConstants.PAGE_DELETED,
-                                 ObservationConstants.ZONEITEM_DELETED);
+                                 ObservationConstants.ZONEITEM_DELETED,
+                                 ObservationConstants.TAG_ADDED,
+                                 ObservationConstants.TAG_DELETED);
         }
         else if ("live".equals(workspace))
         {
@@ -66,7 +68,9 @@
                                  ObservationConstants.PAGE_CHANGED,
                                  ObservationConstants.PAGE_MOVED,   // if the page is moved out of a validated parent
                                  ObservationConstants.PAGE_DELETED,
-                                 ObservationConstants.ZONEITEM_DELETED);
+                                 ObservationConstants.ZONEITEM_DELETED,
+                                 ObservationConstants.TAG_ADDED,
+                                 ObservationConstants.TAG_DELETED);
         }
         
         return Collections.emptyList();
Index: main/plugin-calendar/plugin.xml
===================================================================
--- main/plugin-calendar/plugin.xml	(revision 26702)
+++ main/plugin-calendar/plugin.xml	(working copy)
@@ -182,7 +182,10 @@
                     <parameter name="tag-categories" type="string" multiple="true">
                         <label i18n="true">CALENDAR_SERVICE_AGENDA_TAG_CATEGORIES_LABEL</label>
                         <description i18n="true">CALENDAR_SERVICE_AGENDA_TAG_CATEGORIES_DESC</description>
-                        <widget>content-tag-categories</widget>
+                        <widget>content-tags</widget>
+                        <widget-params>
+                            <param name="onlyTagsWithChildren">true</param>
+                        </widget-params>
                     </parameter>
                     <parameter name="months-before" type="long">
                         <label i18n="true">CALENDAR_SERVICE_AGENDA_MONTHS_BEFORE_LABEL</label>