diff --git a/src/main/java/org/olat/collaboration/CollaborationTools.java b/src/main/java/org/olat/collaboration/CollaborationTools.java
index 2dff99d23e78423b70da0e15c811477b842fe65f..8fa39d569c89418703edbfb186f3939db6ba2bb0 100644
--- a/src/main/java/org/olat/collaboration/CollaborationTools.java
+++ b/src/main/java/org/olat/collaboration/CollaborationTools.java
@@ -261,7 +261,6 @@ public class CollaborationTools implements Serializable {
 	}
 
 	/**
-	 * TODO: rename to getForumController and save instance?
 	 * 
 	 * @param ureq
 	 * @param wControl
@@ -344,8 +343,8 @@ public class CollaborationTools implements Serializable {
 		if(forumProperty != null) {
 			forum = fom.loadForum(forumProperty.getLongValue());
 		} else {
-			//TODO gsync
 			forum = coordinatorManager.getCoordinator().getSyncer().doInSync(ores, new SyncerCallback<Forum>(){
+				@Override
 				public Forum execute() {
 					Forum aforum;
 					Long forumKey;
@@ -449,7 +448,7 @@ public class CollaborationTools implements Serializable {
 		// add linking
 		List<RepositoryEntry> repoEntries = CoreSpringFactory.getImpl(BusinessGroupService.class).findRepositoryEntries(Collections.singleton(businessGroup), 0, -1);
 		
-		List<ICourse> courses = new ArrayList<ICourse>(repoEntries.size());
+		List<ICourse> courses = new ArrayList<>(repoEntries.size());
 		for (RepositoryEntry repoEntry:repoEntries) {
 			if (repoEntry.getOlatResource().getResourceableTypeName().equals(CourseModule.getCourseTypeName())) {
 				ICourse course = CourseFactory.loadCourse(repoEntry);
@@ -461,11 +460,11 @@ public class CollaborationTools implements Serializable {
 			calRenderWrapper.setLinkProvider(clp);
 		}
 
-		List<KalendarRenderWrapper> calendars = new ArrayList<KalendarRenderWrapper>();
+		List<KalendarRenderWrapper> calendars = new ArrayList<>();
 		calendars.add(calRenderWrapper);
 		
 		return new WeeklyCalendarController(ureq, wControl, calendars,
-				WeeklyCalendarController.CALLER_COLLAB, false);
+				WeeklyCalendarController.CALLER_COLLAB, businessGroup, false);
 	}
 
 	/**
@@ -535,7 +534,6 @@ public class CollaborationTools implements Serializable {
 		if(mapProperty != null) {
 			return createPortfolioController(ureq, wControl, stackPanel, mapProperty);
 		} else {
-			//TODO gsync
 			return coordinatorManager.getCoordinator().getSyncer().doInSync(ores, new SyncerCallback<Controller>() {
 				@Override
 				public Controller execute() {
@@ -744,8 +742,8 @@ public class CollaborationTools implements Serializable {
 		// handle Boolean Values via String Field in Property DB Table
 		final String toolValueStr = toolValue ? TRUE : FALSE;
 		final PropertyManager pm = PropertyManager.getInstance();
-		//TODO gsync
 		coordinatorManager.getCoordinator().getSyncer().doInSync(ores, new SyncerExecutor() {
+			@Override
 			public void execute() {				
 				//was: synchronized (CollaborationTools.class) {
 				Property property = getPropertyOf(selectedTool);
@@ -942,10 +940,12 @@ public class CollaborationTools implements Serializable {
 			}
 		}
 
+		@Override
 		public boolean canRead() {
 			return true;
 		}
 
+		@Override
 		public boolean canWrite() {
 			return write;
 		}
@@ -955,30 +955,37 @@ public class CollaborationTools implements Serializable {
 			return write;
 		}
 
+		@Override
 		public boolean canDelete() {
 			return write;
 		}
 
+		@Override
 		public boolean canList() {
 			return true;
 		}
 
+		@Override
 		public boolean canCopy() {
 			return true;
 		}
-		
+
+		@Override
 		public boolean canDeleteRevisionsPermanently() {
 			return write;
 		}
 
+		@Override
 		public Quota getQuota() {
 			return folderQuota;
 		}
 
+		@Override
 		public void setQuota(Quota quota) {
 			this.folderQuota = quota;
 		}
 
+		@Override
 		public SubscriptionContext getSubscriptionContext() {
 			return subsContext;
 		}
diff --git a/src/main/java/org/olat/commons/calendar/CalendarManager.java b/src/main/java/org/olat/commons/calendar/CalendarManager.java
index 0d12715d850d3bf04b68599d86b704ea047e4a3e..2650a09cf1807a36cfe8f6fe88fd546e0102e89a 100644
--- a/src/main/java/org/olat/commons/calendar/CalendarManager.java
+++ b/src/main/java/org/olat/commons/calendar/CalendarManager.java
@@ -233,11 +233,19 @@ public interface CalendarManager {
 	
 	public CalendarUserConfiguration saveCalendarConfig(CalendarUserConfiguration configuration);
 	
+	/**
+	 * 
+	 * @param identity The user which want a token
+	 * @return A configuration with a security token
+	 */
 	public CalendarUserConfiguration createAggregatedCalendarConfig(Identity identity);
 	
+	public CalendarUserConfiguration createCalendarConfig(Identity identity, Kalendar calendar);
+	
 	public List<CalendarUserConfiguration> getCalendarUserConfigurationsList(IdentityRef identity, String... types);
 	
-
+	public CalendarUserConfiguration getCalendarUserConfiguration(IdentityRef identity, Kalendar calendar);
+	
 	public CalendarUserConfiguration getCalendarUserConfiguration(Long key);
 
 	/**
diff --git a/src/main/java/org/olat/commons/calendar/ICalServlet.java b/src/main/java/org/olat/commons/calendar/ICalServlet.java
index 860cb4d2497c6e2a8d1cdc47edb0fb619d7d9c2e..ad8ee92c9832b26102349b237decb762ecb0ad65 100644
--- a/src/main/java/org/olat/commons/calendar/ICalServlet.java
+++ b/src/main/java/org/olat/commons/calendar/ICalServlet.java
@@ -214,7 +214,7 @@ public class ICalServlet extends HttpServlet {
 		if(CalendarManager.TYPE_USER_AGGREGATED.equals(calendarType)) {
 			// check the authentication token
 			CalendarUserConfiguration config = calendarManager.getCalendarUserConfiguration(Long.parseLong(userName));
-			String savedToken = config.getToken();
+			String savedToken = config == null ? null : config.getToken();
 			if (authToken == null || savedToken == null || !savedToken.equals(authToken)) {
 				log.warn("Authenticity Check failed for the ical feed path: " + pathInfo);
 				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, requestUrl);
@@ -223,7 +223,13 @@ public class ICalServlet extends HttpServlet {
 			}
 		} else if (calendarManager.calendarExists(calendarType, calendarID)) {
 			// check the authentication token
-			String savedToken = calendarManager.getCalendarToken(calendarType, calendarID, userName);
+			String savedToken = null;
+			if(StringHelper.isLong(userName)) {
+				CalendarUserConfiguration config = calendarManager.getCalendarUserConfiguration(Long.parseLong(userName));
+				savedToken = config == null ? null : config.getToken();
+			} else {
+				savedToken = calendarManager.getCalendarToken(calendarType, calendarID, userName);
+			}
 			if (authToken == null || savedToken == null || !savedToken.equals(authToken)) {
 				log.warn("Authenticity Check failed for the ical feed path: " + pathInfo);
 				response.sendError(HttpServletResponse.SC_UNAUTHORIZED, requestUrl);
diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties
index 307bbabc12e607ecd01c6e02da015dee955a6d5c..cb7ea9701cc395c63d4ebd21072bd3b118999171 100644
--- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_de.properties
@@ -67,7 +67,7 @@ cal.fri=Freitag
 cal.from=Von
 cal.goto.event=Gehe zu gew\u00E4hltem Termin
 cal.icalfeed.aggregated.info=Bitte benutzen Sie die folgende URL, um diesen Kalender (inklusive aller aggregierten Kalender) von anderen Anwendungen aus aufzurufen. Sie k\u00F6nnen die URL kopieren und in jede andere Kalenderanwendung einf\u00FCgen, welche das iCal-Format unterst\u00FCtzt.
-cal.icalfeed.aggregated.title=Aggregiertes iCal Feed-Link
+cal.icalfeed.aggregated.title=Pers\u00F6nliches aggregiertes iCal Feed-Link
 cal.icalfeed.aggregated.tooltip=$\:cal.icalfeed.aggregated.title
 cal.icalfeed.info=Bitte benutzen Sie die folgende URL, um diesen Kalender von anderen Anwendungen aus aufzurufen. Sie k\u00F6nnen die URL kopieren und in jede andere Kalenderanwendung einf\u00FCgen, welche das iCal-Format unterst\u00FCtzt.
 cal.icalfeed.regenerate.info=iCal Feed-Link wurde neu generiert.
diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties
index e81977c427960228a8e6bdab1e893567c9afcbc4..ec0a8664afa3acc578e64d21d506e58f08308a64 100644
--- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties
@@ -67,7 +67,7 @@ cal.fri=Friday
 cal.from=From
 cal.goto.event=Go to selected event
 cal.icalfeed.aggregated.info=Please use the following URL in order to call this calendar (including all aggregated calendars) from other applications. You can copy and paste the URL into any calendar application supporting the iCal format.
-cal.icalfeed.aggregated.title=Aggregated iCal Feed-Link
+cal.icalfeed.aggregated.title=Personal aggregated iCal Feed-Link
 cal.icalfeed.aggregated.tooltip=$\:cal.icalfeed.aggregated.title
 cal.icalfeed.info=Please use the following URL to access your calendar from other applications. You can copy and paste this to any other application supporting the iCal format.
 cal.icalfeed.regenerate.info=ICal Feed Link has been regenerated.
diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_fr.properties
index 3c84e04a0cd7589e642679deb4305ac47d65becf..953e9741b1778e4fdd2f97a91ab3601c899b18b1 100644
--- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_fr.properties
@@ -67,7 +67,7 @@ cal.fri=Vendredi
 cal.from=De
 cal.goto.event=Aller au rdv. s\u00E9lectionn\u00E9
 cal.icalfeed.aggregated.info=Utilisez le lien suivant pour l'acc\u00E8s de votre calendrier  (tous les calendriers agr\u00E9g\u00E9 inclus) \u00E0 partir d'autres applications. Vous pouvez copier le lien et le coller dans une application qui prend en charge le format iCal.
-cal.icalfeed.aggregated.title=Flux iCal des calendriers agr\u00E9g\u00E9s
+cal.icalfeed.aggregated.title=Flux agr\u00E9g\u00E9 et personalis\u00E9 des calendriers iCal
 cal.icalfeed.aggregated.tooltip=$\:cal.icalfeed.aggregated.title
 cal.icalfeed.info=Veuillez utiliser l'URL suivante pour appeler ce calendrier depuis une autre application. Vous pouvez copier l'URL et l'ins\u00E9rer dans toute autre application de calendrier qui supporte le format iCal.
 cal.icalfeed.regenerate.info=Le lien iCal Feed a \u00E9t\u00E9 r\u00E9actualis\u00E9.
diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_it.properties
index 9830903553bd23923da65862f4f82c7fe053d798..8797b41ef60d1cbe624891c8c964b5461f251cdb 100644
--- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_it.properties
+++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_it.properties
@@ -67,7 +67,6 @@ cal.fri=Venerd\u00EC
 cal.from=Da
 cal.goto.event=Vai all'impegno selezionato
 cal.icalfeed.aggregated.info=Utilizzare il seguente URL per richiamare questo calendario (inclusi tutti i calendari aggregati) da altre applicazioni. \u00C8 possibile copiare e incollare l'URL all'interno di qualsiasi applicazione di calendario che supporti il formato iCal.
-cal.icalfeed.aggregated.title=Feed-link iCal aggregato
 cal.icalfeed.aggregated.tooltip=$\:cal.icalfeed.aggregated.title
 cal.icalfeed.info=Utilizzi questo URL per accedere a questo calendario da altre applicazioni. La pu\u00F2 copiare e incollare in qualsiasi altra applicazione calendario che supporta il formato iCal.
 cal.icalfeed.regenerate.info=Il feed link iCal \u00E8 stato rigenerato.
diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pt_BR.properties
index 530193a9d73c45dac87a2d6d0308b73d23b16549..e42ab131f526869c5dd56e16f2e98cc0c6871fa0 100644
--- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pt_BR.properties
@@ -67,7 +67,6 @@ cal.fri=Sexta
 cal.from=De
 cal.goto.event=Ir para evento selecionado
 cal.icalfeed.aggregated.info=Utilize a seguinte URL, a fim de chamar este calend\u00E1rio (incluindo todos os calend\u00E1rios agregados) a partir de outras aplica\u00E7\u00F5es. Voc\u00EA pode copiar e colar a URL em qualquer aplica\u00E7\u00E3o de calend\u00E1rio que suporte o formato iCal.
-cal.icalfeed.aggregated.title=Feed-Link iCal agragado
 cal.icalfeed.aggregated.tooltip=$\:cal.icalfeed.aggregated.title
 cal.icalfeed.info=Por favor, use a seguinte URL para acessar sua agenda de outras aplica\u00E7\u00F5es. Voc\u00EA pode copiar e colar este para qualquer outra aplica\u00E7\u00E3o de suporte ao formato iCal.
 cal.icalfeed.regenerate.info=ICal Feed-Link foi regenerado.
diff --git a/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java b/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java
index dcd2f430b35db228e3e57de289158af79791b01e..e5b3d11bd17963ae07a9f5d56a5d3d93c7c89cae 100644
--- a/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java
+++ b/src/main/java/org/olat/commons/calendar/manager/ICalFileCalendarManager.java
@@ -429,6 +429,13 @@ public class ICalFileCalendarManager implements CalendarManager, InitializingBea
 				token, false, false);
 	}
 
+	@Override
+	public CalendarUserConfiguration createCalendarConfig(Identity identity, Kalendar calendar) {
+		String token = RandomStringUtils.randomAlphanumeric(6);
+		return calendarUserConfigDao.createCalendarUserConfiguration(calendar, identity,
+				token, false, false);
+	}
+
 	@Override
 	public CalendarUserConfiguration saveCalendarConfig(CalendarUserConfiguration configuration) {
 		return calendarUserConfigDao.update(configuration);
@@ -444,6 +451,11 @@ public class ICalFileCalendarManager implements CalendarManager, InitializingBea
 		return calendarUserConfigDao.getCalendarUserConfigurations(identity, types);
 	}
 	
+	@Override
+	public CalendarUserConfiguration getCalendarUserConfiguration(IdentityRef identity, Kalendar calendar) {
+		return calendarUserConfigDao.getCalendarUserConfiguration(identity, calendar.getCalendarID(), calendar.getType());
+	}
+
 	@Override
 	public Map<CalendarKey,CalendarUserConfiguration> getCalendarUserConfigurationsMap(IdentityRef identity, String... types) {
 		List<CalendarUserConfiguration> list = calendarUserConfigDao.getCalendarUserConfigurations(identity, types);
diff --git a/src/main/java/org/olat/commons/calendar/ui/CalendarAggregatedURLController.java b/src/main/java/org/olat/commons/calendar/ui/CalendarAggregatedURLController.java
index 8ce24a9d892064b6a26ed6019fbb9781f2405c3b..c9451c3c4ce9447029ce846d9584dbf25ed30a83 100644
--- a/src/main/java/org/olat/commons/calendar/ui/CalendarAggregatedURLController.java
+++ b/src/main/java/org/olat/commons/calendar/ui/CalendarAggregatedURLController.java
@@ -26,6 +26,7 @@ import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 
 /**
@@ -36,13 +37,18 @@ import org.olat.core.util.Util;
  */
 public class CalendarAggregatedURLController extends BasicController {
 
-	public CalendarAggregatedURLController(UserRequest ureq, WindowControl wControl, String icalFeedLink) {
+	public CalendarAggregatedURLController(UserRequest ureq, WindowControl wControl, String icalFeedLink, String icalAggregatedFeedLink) {
 		super(ureq, wControl);
 		setTranslator(Util.createPackageTranslator(CalendarManager.class, getLocale(), getTranslator()));
 		
-		VelocityContainer colorVC = createVelocityContainer("calAggregatedFeed");
-		colorVC.contextPut("icalFeedLink", icalFeedLink);
-		putInitialPanel(colorVC);
+		VelocityContainer mainVC = createVelocityContainer("calAggregatedFeed");
+		if(StringHelper.containsNonWhitespace(icalFeedLink)) {
+			mainVC.contextPut("icalFeedLink", icalFeedLink);
+		}
+		if(StringHelper.containsNonWhitespace(icalAggregatedFeedLink)) {
+			mainVC.contextPut("icalAggregatedFeedLink", icalAggregatedFeedLink);
+		}
+		putInitialPanel(mainVC);
 	}
 	
 	@Override
diff --git a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java
index e46702e1e2864a07d8a7eb69fd12107b348e5a98..ede144f93f25d68937bd42fbb9ac6a51c92641d9 100644
--- a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java
+++ b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java
@@ -77,6 +77,7 @@ import org.olat.core.gui.control.generic.modal.DialogBoxController;
 import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.gui.control.winmgr.JSCommand;
 import org.olat.core.helpers.Settings;
+import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.UserConstants;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.core.id.context.ContextEntry;
@@ -124,6 +125,7 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 	private final String caller;
 	private boolean dirty = false;
 	private final boolean allowImport;
+	private final OLATResourceable callerOres;
 
 	private List<KalendarRenderWrapper> calendarWrappers;
 	
@@ -149,13 +151,14 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 	 * @param eventAlwaysVisible  When true, the 'isVis()' check is disabled and events will be displayed always.
 	 */
 	public WeeklyCalendarController(UserRequest ureq, WindowControl wControl, List<KalendarRenderWrapper> calendarWrappers,
-			String caller, boolean allowImport) {
+			String caller, OLATResourceable callerOres, boolean allowImport) {
 		super(ureq,wControl, "indexWeekly");
 		setTranslator(Util.createPackageTranslator(CalendarManager.class, ureq.getLocale(), getTranslator()));
-		
+
+		this.caller = caller;
 		this.allowImport = allowImport;
 		this.calendarWrappers = calendarWrappers;
-		this.caller = caller;
+		this.callerOres = callerOres == null ? null : OresHelper.clone(callerOres);
 		
 		String themeBaseUri = wControl.getWindowBackOffice().getWindow().getGuiTheme().getBaseURI();
 		printMapper = new CalendarPrintMapper(themeBaseUri, getTranslator());
@@ -315,7 +318,7 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 					doConfigure(ureq);
 				} else if(CalendarGUIFormEvent.AGGREGATED_FEED.equals(cmd)) {
 					CalendarGUIFormEvent guiEvent = (CalendarGUIFormEvent)event;
-					doOpenAggregatedFeelUrl(ureq, guiEvent.getTargetDomId());
+					doOpenAggregatedFeedUrl(ureq, guiEvent.getTargetDomId());
 				}
 			} else if (event instanceof CalendarGUIPrintEvent) {
 				CalendarGUIPrintEvent printEvent = (CalendarGUIPrintEvent)event;
@@ -486,7 +489,54 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 		}
 	}
 	
-	private void doOpenAggregatedFeelUrl(UserRequest ureq, String targetDomId) {
+	private void doOpenAggregatedFeedUrl(UserRequest ureq, String targetDomId) {
+		String callerUrl = getCallerCalendarUrl();
+		String aggregatedUrl = getAggregatedCalendarUrl();
+		feedUrlCtrl = new CalendarAggregatedURLController(ureq, getWindowControl(), callerUrl, aggregatedUrl);
+		listenTo(feedUrlCtrl);
+		
+		eventCalloutCtr = new CloseableCalloutWindowController(ureq, getWindowControl(), feedUrlCtrl.getInitialComponent(), targetDomId,
+				translate("print"), true, "o_cal_event_callout");
+		listenTo(eventCalloutCtr);
+		eventCalloutCtr.activate();
+	}
+	
+	private String getCallerCalendarUrl() {
+		if(callerOres == null) return null;
+		
+		String url = null;
+		if(WeeklyCalendarController.CALLER_COLLAB.equals(caller)) {
+			url = getCallerCalendarUrl(CalendarManager.TYPE_GROUP, callerOres.getResourceableId().toString());
+		} else if(WeeklyCalendarController.CALLER_COURSE.equals(caller)) {
+			url = getCallerCalendarUrl(CalendarManager.TYPE_COURSE, callerOres.getResourceableId().toString());
+		}
+		return url;
+	}
+	
+	private String getCallerCalendarUrl(String type, String calendarId) {
+		Kalendar callerKalendar = null;
+		for(KalendarRenderWrapper calendarWrapper:calendarWrappers) {
+			if(calendarWrapper.getKalendar().getType().equals(type) && calendarWrapper.getKalendar().getCalendarID().equals(calendarId)) {
+				callerKalendar = calendarWrapper.getKalendar();
+				break;
+			}
+		}
+		
+		if(callerKalendar != null) {
+			CalendarUserConfiguration config = calendarManager.getCalendarUserConfiguration(getIdentity(), callerKalendar);
+			if(config == null) {
+				config = calendarManager.createCalendarConfig(getIdentity(), callerKalendar);
+			} else if(!StringHelper.containsNonWhitespace(config.getToken())) {
+				config.setToken(RandomStringUtils.randomAlphanumeric(6));
+				config = calendarManager.saveCalendarConfig(config);
+			}
+			return Settings.getServerContextPathURI() + "/ical/" + type + "/" + config.getKey()
+				+ "/" + config.getToken() + "/" + callerKalendar.getCalendarID() + ".ics";
+		}
+		return null;
+	}
+	
+	private String getAggregatedCalendarUrl() {
 		List<CalendarUserConfiguration> configurations = calendarManager
 				.getCalendarUserConfigurationsList(getIdentity(), CalendarManager.TYPE_USER_AGGREGATED);
 
@@ -500,17 +550,8 @@ public class WeeklyCalendarController extends FormBasicController implements Act
 			config.setToken(RandomStringUtils.randomAlphanumeric(6));
 			config = calendarManager.saveCalendarConfig(config);
 		}
-		
-		String token = config.getToken();
-		Long configKey = config.getKey();
-		String url = Settings.getServerContextPathURI() + "/ical/" + CalendarManager.TYPE_USER_AGGREGATED + "/" + configKey + "/" + token + ".ics"; 	
-		feedUrlCtrl = new CalendarAggregatedURLController(ureq, getWindowControl(), url);
-		listenTo(feedUrlCtrl);
-		
-		eventCalloutCtr = new CloseableCalloutWindowController(ureq, getWindowControl(), feedUrlCtrl.getInitialComponent(), targetDomId,
-				translate("print"), true, "o_cal_event_callout");
-		listenTo(eventCalloutCtr);
-		eventCalloutCtr.activate();
+		return Settings.getServerContextPathURI() + "/ical/" + CalendarManager.TYPE_USER_AGGREGATED
+				+ "/" + config.getKey() + "/" + config.getToken() + ".ics";
 	}
 	
 	private void doConfigure(UserRequest ureq) {
diff --git a/src/main/java/org/olat/commons/calendar/ui/_content/calAggregatedFeed.html b/src/main/java/org/olat/commons/calendar/ui/_content/calAggregatedFeed.html
index 938702f077524739ec1df6cd703193f8a95a2dc7..84cc75d84018efa4a1881fc684cb6ece90f811d9 100644
--- a/src/main/java/org/olat/commons/calendar/ui/_content/calAggregatedFeed.html
+++ b/src/main/java/org/olat/commons/calendar/ui/_content/calAggregatedFeed.html
@@ -1,3 +1,10 @@
-<h4>$r.translate("cal.icalfeed.aggregated.title")</h4>
-<div class="o_info">$r.translate("cal.icalfeed.aggregated.info")</div>
-<div class="clearfix"><input type="text" value="$icalFeedLink" style="width:100%;" onclick="this.select();"/></div>
\ No newline at end of file
+#if($r.isNotEmpty($icalFeedLink))
+	<h4>$r.translate("cal.icalfeed.title")</h4>
+	<div class="o_info">$r.translate("cal.icalfeed.info")</div>
+	<div class="clearfix"><input type="text" value="$icalFeedLink" style="width:100%;" onclick="this.select();"/></div>
+#end
+#if($r.isNotEmpty($icalAggregatedFeedLink))
+	<h4>$r.translate("cal.icalfeed.aggregated.title")</h4>
+	<div class="o_info">$r.translate("cal.icalfeed.aggregated.info")</div>
+	<div class="clearfix"><input type="text" value="$icalAggregatedFeedLink" style="width:100%;" onclick="this.select();"/></div>
+#end
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/cal/CourseCalendarController.java b/src/main/java/org/olat/course/nodes/cal/CourseCalendarController.java
index 9128ed7bf8fc251411789dc3f376a024382b5ce7..4c1ff4122ce42d3ed10db9c35fc9b2c6b628de81 100644
--- a/src/main/java/org/olat/course/nodes/cal/CourseCalendarController.java
+++ b/src/main/java/org/olat/course/nodes/cal/CourseCalendarController.java
@@ -64,8 +64,8 @@ public class CourseCalendarController extends DefaultController implements Clone
 		this.nodeEvaluation = ne;
 		calendars = myCal.getCalendars();
 		courseKalendarWrapper = myCal.getCourseKalendarWrapper();
-		calendarController = new WeeklyCalendarController(ureq, wControl, calendars,
-				WeeklyCalendarController.CALLER_COURSE, false);
+		calendarController = new WeeklyCalendarController(ureq, wControl, calendars, WeeklyCalendarController.CALLER_COURSE,
+				courseEnv.getCourseEnvironment().getCourseGroupManager().getCourseResource(), false);
 		calendarController.setDifferentiateManagedEvent(needToDifferentiateManagedEvents(calendars));
 		setInitialComponent(calendarController.getInitialComponent());
 	}
diff --git a/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java b/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java
index 566558401b477a36339ade71d472b9b163f2bf89..ef5ab9a8d36a2e80994801cddbf60e78a178b7e0 100644
--- a/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java
+++ b/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java
@@ -71,8 +71,8 @@ public class CourseCalendarController extends BasicController {
 		super(ureq, wControl);
 		this.userCourseEnv = userCourseEnv;
 		List<KalendarRenderWrapper> calendars = getListOfCalendarWrappers(ureq);
-		calendarController = new WeeklyCalendarController(ureq, wControl, calendars,
-				WeeklyCalendarController.CALLER_COURSE, false);
+		calendarController = new WeeklyCalendarController(ureq, wControl, calendars, WeeklyCalendarController.CALLER_COURSE,
+				userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseResource(), false);
 		calendarController.setDifferentiateManagedEvent(needToDifferentiateManagedEvents(calendars));
 		listenTo(calendarController);
 		putInitialPanel(calendarController.getInitialComponent());
@@ -88,7 +88,7 @@ public class CourseCalendarController extends BasicController {
 	}
 
 	private List<KalendarRenderWrapper> getListOfCalendarWrappers(UserRequest ureq) {
-		List<KalendarRenderWrapper> calendars = new ArrayList<KalendarRenderWrapper>();
+		List<KalendarRenderWrapper> calendars = new ArrayList<>();
 		// add course calendar
 		ICourse course = CourseFactory.loadCourse(userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry());
 		courseKalendarWrapper = calendarManager.getCourseCalendar(course);
diff --git a/src/main/java/org/olat/group/ui/homepage/GroupInfoMainController.java b/src/main/java/org/olat/group/ui/homepage/GroupInfoMainController.java
index 280d59c4934e51f3bfc315ae38b00d7a72475529..7a953bde5a55f817a2e72fb3089dc4027843939d 100644
--- a/src/main/java/org/olat/group/ui/homepage/GroupInfoMainController.java
+++ b/src/main/java/org/olat/group/ui/homepage/GroupInfoMainController.java
@@ -218,7 +218,8 @@ public class GroupInfoMainController extends MainLayoutBasicController implement
 			KalendarRenderWrapper groupCalendar = calendarManager.getGroupCalendar(businessGroup);
 			groupCalendar.setPrivateEventsVisible(false);
 			calendarWrappers.add(groupCalendar);
-			calendarController = new WeeklyCalendarController(ureq, bwControl, calendarWrappers, WeeklyCalendarController.CALLER_COLLAB, false);
+			calendarController = new WeeklyCalendarController(ureq, bwControl, calendarWrappers,
+					WeeklyCalendarController.CALLER_COLLAB, businessGroup, false);
 			listenTo(calendarController);
 		}
 		
diff --git a/src/main/java/org/olat/home/HomeCalendarController.java b/src/main/java/org/olat/home/HomeCalendarController.java
index 9e605999f8d920e5ad7745dc0925723bf94d72ea..a41fc592b3f4b0432adbe6384162e7a4e875948b 100644
--- a/src/main/java/org/olat/home/HomeCalendarController.java
+++ b/src/main/java/org/olat/home/HomeCalendarController.java
@@ -63,7 +63,7 @@ public class HomeCalendarController extends BasicController implements Activatea
 		
 		List<KalendarRenderWrapper> calendars = homeCalendarManager.getListOfCalendarWrappers(ureq, windowControl);
 		calendarController = new WeeklyCalendarController(ureq, windowControl, calendars,
-				WeeklyCalendarController.CALLER_HOME, true);
+				WeeklyCalendarController.CALLER_HOME, null, true);
 		listenTo(calendarController);
 
 		putInitialPanel(calendarController.getInitialComponent());
diff --git a/src/main/java/org/olat/user/UserInfoMainController.java b/src/main/java/org/olat/user/UserInfoMainController.java
index e5ae1449d6819e4fdc2bf1f694d41f579b415c1a..e1c367cb292510d1d12467d3a937f1724915a66b 100644
--- a/src/main/java/org/olat/user/UserInfoMainController.java
+++ b/src/main/java/org/olat/user/UserInfoMainController.java
@@ -344,7 +344,7 @@ public class UserInfoMainController extends MainLayoutBasicController implements
 		OLATResourceable ores = OresHelper.createOLATResourceableType(CMD_CALENDAR);
 		WindowControl bwControl = addToHistory(ureq, ores, null);
 		calendarController = new WeeklyCalendarController(ureq, bwControl, calendars,
-				WeeklyCalendarController.CALLER_PROFILE, false);
+				WeeklyCalendarController.CALLER_PROFILE, null, false);
 		listenTo(calendarController);
 		return calendarController;
 	}