diff --git a/src/main/java/org/olat/commons/calendar/CalendarManager.java b/src/main/java/org/olat/commons/calendar/CalendarManager.java
index f233b86460eb24ce6973f9f0f9ad457fa21ac8fb..9b48c3b5b91d1dbc4dac4acf2b9c78890275e035 100644
--- a/src/main/java/org/olat/commons/calendar/CalendarManager.java
+++ b/src/main/java/org/olat/commons/calendar/CalendarManager.java
@@ -48,6 +48,12 @@ public interface CalendarManager {
 	public static final String TYPE_GROUP = "group";
 	public static final String TYPE_COURSE = "course";
 	
+	public static final String ICAL_X_OLAT_LINK = "X-OLAT-LINK";
+	public static final String ICAL_X_OLAT_COMMENT = "X-OLAT-COMMENT";
+	public static final String ICAL_X_OLAT_NUMPARTICIPANTS = "X-OLAT-NUMPARTICIPANTS";
+	public static final String ICAL_X_OLAT_PARTICIPANTS = "X-OLAT-PARTICIPANTS";
+	public static final String ICAL_X_OLAT_SOURCENODEID = "X-OLAT-SOURCENODEID";
+	
 	public static final int MAX_SUBJECT_DISPLAY_LENGTH = 30;
 
 	/**
diff --git a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java
index d9c5bc09aff530c7c37de7e5c8642cbcda8debaa..29a4c4519ad16acf833451fe6fb1b633dcfcef34 100644
--- a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java
+++ b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java
@@ -36,6 +36,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.StringReader;
+import java.net.URISyntaxException;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Date;
@@ -73,7 +74,6 @@ import org.olat.group.BusinessGroup;
 import net.fortuna.ical4j.data.CalendarBuilder;
 import net.fortuna.ical4j.data.CalendarOutputter;
 import net.fortuna.ical4j.model.Calendar;
-import net.fortuna.ical4j.model.Component;
 import net.fortuna.ical4j.model.DateList;
 import net.fortuna.ical4j.model.DateTime;
 import net.fortuna.ical4j.model.Parameter;
@@ -96,6 +96,7 @@ import net.fortuna.ical4j.model.property.ProdId;
 import net.fortuna.ical4j.model.property.RRule;
 import net.fortuna.ical4j.model.property.Summary;
 import net.fortuna.ical4j.model.property.Uid;
+import net.fortuna.ical4j.model.property.Url;
 import net.fortuna.ical4j.model.property.Version;
 import net.fortuna.ical4j.model.property.XProperty;
 
@@ -111,13 +112,6 @@ public class ICalFileCalendarManager implements CalendarManager {
 	private static final Clazz ICAL_CLASS_PUBLIC = new Clazz("PUBLIC");
 	private static final Clazz ICAL_CLASS_X_FREEBUSY = new Clazz("X-FREEBUSY");
 	
-	private static final String ICAL_X_OLAT_LINK = "X-OLAT-LINK";
-	
-	private static final String ICAL_X_OLAT_COMMENT = "X-OLAT-COMMENT";
-	private static final String ICAL_X_OLAT_NUMPARTICIPANTS = "X-OLAT-NUMPARTICIPANTS";
-	private static final String ICAL_X_OLAT_PARTICIPANTS = "X-OLAT-PARTICIPANTS";
-	private static final String ICAL_X_OLAT_SOURCENODEID = "X-OLAT-SOURCENODEID";
-	
 	/** rule for recurring events */
 	private static final String ICAL_RRULE = "RRULE";
 	/** property to exclude events from recurrence */
@@ -201,14 +195,14 @@ public class ICalFileCalendarManager implements CalendarManager {
 	// o_clusterOK by:cg This must not be synchronized because the caller already synchronized 
 	private Kalendar loadCalendarFromFile(String type, String calendarID) {
 		Calendar calendar = readCalendar(type, calendarID);
-    Kalendar kalendar = createKalendar(type, calendarID, calendar);
+		Kalendar kalendar = createKalendar(type, calendarID, calendar);
 		return kalendar;
 	}
 
 	private Kalendar createKalendar(String type, String calendarID, Calendar calendar) {
 		Kalendar cal = new Kalendar(calendarID, type);
-		for (Iterator iter = calendar.getComponents().iterator(); iter.hasNext();) {
-			Component comp = (Component) iter.next();
+		for (Iterator<?> iter = calendar.getComponents().iterator(); iter.hasNext();) {
+			Object comp = iter.next();
 			if (comp instanceof VEvent) {
 				VEvent vevent = (VEvent)comp;
 				KalendarEvent calEvent = getKalendarEvent(vevent);
@@ -227,29 +221,26 @@ public class ICalFileCalendarManager implements CalendarManager {
    * Internal read calendar file from filesystem
    */
 	@Override
-  public Calendar readCalendar(String type, String calendarID) {
-  	log.debug("readCalendar from file, type=" + type + "  calendarID=" + calendarID);
+	public Calendar readCalendar(String type, String calendarID) {
+		if(log.isDebug()) {
+			log.debug("readCalendar from file, type=" + type + "  calendarID=" + calendarID);
+		}
+		
 		File calendarFile = getCalendarFile(type, calendarID);
     
-		InputStream in = null;
-		try {
-			in = new BufferedInputStream(new FileInputStream(calendarFile));
+		Calendar calendar;
+		try(InputStream fIn = new FileInputStream(calendarFile);
+				InputStream	in = new BufferedInputStream(fIn))  {
+			
+			CalendarBuilder builder = new CalendarBuilder();
+			calendar = builder.build(in);
 		} catch (FileNotFoundException fne) {
 			throw new OLATRuntimeException("Not found: " + calendarFile, fne);
-		}
-		
-		CalendarBuilder builder = new CalendarBuilder();
-		Calendar calendar = null;
-		try {
-			calendar = builder.build(in);
 		} catch (Exception e) {
 			throw new OLATRuntimeException("Error parsing calendar file.", e);
-		} finally {
-			if (in != null)
-				FileUtils.closeSafely(in);
 		}
-    return calendar;
-  }
+		return calendar;
+	}
 
 	@Override
   public Kalendar buildKalendarFrom(String calendarContent, String calType, String calId) {
@@ -410,6 +401,7 @@ public class ICalFileCalendarManager implements CalendarManager {
 		}
 		
 		// event links
+		Url urlOnce = null;
 		List<KalendarEventLink> kalendarEventLinks = kEvent.getKalendarEventLinks();
 		if ((kalendarEventLinks != null) && !kalendarEventLinks.isEmpty()) {
 			for (Iterator<KalendarEventLink> iter = kalendarEventLinks.iterator(); iter.hasNext();) {
@@ -426,8 +418,20 @@ public class ICalFileCalendarManager implements CalendarManager {
 				linkEncoded.append(link.getIconCssClass());
 				XProperty linkProperty = new XProperty(ICAL_X_OLAT_LINK, linkEncoded.toString());
 				vEventProperties.add(linkProperty);
+				if(urlOnce == null) {
+					try {
+						Url url = new Url();
+						url.setValue(link.getURI());
+						urlOnce = url;
+					} catch (URISyntaxException e) {
+						log.error("Invalid URL:" + link.getURI());
+					}
+				}
 			}
 		}
+		if(urlOnce != null) {
+			vEventProperties.add(urlOnce);
+		}
 		
 		if (kEvent.getComment() != null) {
 			vEventProperties.add(new XProperty(ICAL_X_OLAT_COMMENT, kEvent.getComment()));
@@ -512,13 +516,13 @@ public class ICalFileCalendarManager implements CalendarManager {
 			end = new Date(end.getTime() - (1000 * 60 * 60 * 24));
 		}
 		
-		// fxdiff: 
 		Uid eventuid = event.getUid();
 		String uid;
-		if (eventuid != null)
+		if (eventuid != null) {
 			uid = eventuid.getValue();
-		else
+		} else {
 			uid = CodeHelper.getGlobalForeverUniqueID();
+		}
 		KalendarEvent calEvent = new KalendarEvent(uid, subject, start, end);
 		calEvent.setAllDayEvent(isAllDay);
 		
@@ -558,7 +562,7 @@ public class ICalFileCalendarManager implements CalendarManager {
 		// links if any
 		PropertyList linkProperties = event.getProperties(ICAL_X_OLAT_LINK);
 		List<KalendarEventLink> kalendarEventLinks = new ArrayList<KalendarEventLink>();
-		for (Iterator iter = linkProperties.iterator(); iter.hasNext();) {
+		for (Iterator<?> iter = linkProperties.iterator(); iter.hasNext();) {
 			XProperty linkProperty = (XProperty) iter.next();
 			if (linkProperty != null) {
 				String encodedLink = linkProperty.getValue();
@@ -799,7 +803,7 @@ public class ICalFileCalendarManager implements CalendarManager {
 		// inform all controller about calendar change for reload
 		CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(new KalendarModifiedEvent(cal), OresHelper.lookupType(CalendarManager.class));
 		return successfullyPersist;
-  }
+	}
 	
 	public boolean updateCalendar(final Kalendar cal, final Kalendar importedCal) {
 		OLATResourceable calOres = getOresHelperFor(cal);
diff --git a/src/main/java/org/olat/commons/calendar/ICalServlet.java b/src/main/java/org/olat/commons/calendar/ICalServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f0a4598ffb1f74554cc9cf30040656972382b00
--- /dev/null
+++ b/src/main/java/org/olat/commons/calendar/ICalServlet.java
@@ -0,0 +1,294 @@
+/**
+* OLAT - Online Learning and Training<br>
+* http://www.olat.org
+* <p>
+* Licensed under the Apache License, Version 2.0 (the "License"); <br>
+* you may not use this file except in compliance with the License.<br>
+* You may obtain a copy of the License at
+* <p>
+* http://www.apache.org/licenses/LICENSE-2.0
+* <p>
+* Unless required by applicable law or agreed to in writing,<br>
+* software distributed under the License is distributed on an "AS IS" BASIS, <br>
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+* See the License for the specific language governing permissions and <br>
+* limitations under the License.
+* <p>
+* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
+* University of Zurich, Switzerland.
+* <hr>
+* <a href="http://www.openolat.org">
+* OpenOLAT - Online Learning and Training</a><br>
+* This file has been modified by the OpenOLAT community. Changes are licensed
+* under the Apache 2.0 license as the original file.  
+* <p>
+*/ 
+
+package org.olat.commons.calendar;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.olat.core.commons.persistence.DBFactory;
+import org.olat.core.dispatcher.DispatcherModule;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.i18n.I18nManager;
+
+import net.fortuna.ical4j.data.CalendarOutputter;
+import net.fortuna.ical4j.model.Calendar;
+import net.fortuna.ical4j.model.PropertyList;
+import net.fortuna.ical4j.model.ValidationException;
+import net.fortuna.ical4j.model.component.VEvent;
+import net.fortuna.ical4j.model.property.Url;
+import net.fortuna.ical4j.model.property.XProperty;
+
+
+/**
+ * Description:<BR>
+ * Servlet that serves the ical document.
+ * <P>
+ * Initial Date:  June 1, 2008
+ *
+ * @author Udit Sajjanhar
+ */
+public class ICalServlet extends HttpServlet {
+
+	private static final long serialVersionUID = -155266285395912535L;
+	private static final OLog log = Tracing.createLoggerFor(ICalServlet.class);
+
+	/**
+	 * Default constructor.
+	 */
+	public ICalServlet() {
+		//
+	}
+
+	/**
+	 * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+	 */
+	@Override
+	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+		Tracing.setUreq(req);
+		try {
+			super.service(req, resp);
+		} finally {
+			//consume the userrequest.
+			Tracing.setUreq(null);
+			I18nManager.remove18nInfoFromThread();
+			DBFactory.getInstance().commitAndCloseSession();
+		}
+	}
+
+	/**
+	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
+	 *      javax.servlet.http.HttpServletResponse)
+	 */
+	@Override
+	protected void doGet(HttpServletRequest request, HttpServletResponse response) {
+		Calendar icalDoc = null;
+
+		final boolean debug = log.isDebug();
+		try {
+			String pathInfo = request.getPathInfo();
+			if (debug) {
+				log.debug("doGet pathInfo=" + pathInfo);
+			}
+			if ((pathInfo == null) || (pathInfo.equals(""))) {
+				return; // error
+			}
+
+			if (checkPath(pathInfo)) {
+				icalDoc = getIcalDocument(pathInfo);
+				if (icalDoc == null) {
+					DispatcherModule.sendNotFound(pathInfo, response);
+					return;
+				}
+			} else {
+				DispatcherModule.sendNotFound(pathInfo, response);
+				return;
+			}
+
+			// OLAT-5243 related: sending back the reply can take arbitrary
+			// long,
+			// considering slow end-user connections for example - or a sudden
+			// death of the connection
+			// on the client-side which remains unnoticed (network partitioning)
+			DBFactory.getInstance().commitAndCloseSession();
+
+			// output the calendar to the stream
+			CalendarOutputter calOut = new CalendarOutputter(false);
+			calOut.output(icalDoc, response.getOutputStream());
+		} catch (ValidationException e) {
+			// throw olat exception for nice logging
+			log.warn("Validation Error when generate iCal stream for path::" + request.getPathInfo(), e);
+			DispatcherModule.sendNotFound("none", response);
+		} catch (IOException e) {
+			// throw olat exception for nice logging
+			log.warn("IOException Error when generate iCal stream for path::" + request.getPathInfo(), e);
+			DispatcherModule.sendNotFound("none", response);
+		} catch (Exception e) {
+			log.warn("Unknown Error in icalservlet", e);
+			DispatcherModule.sendNotFound("none", response);
+		}
+	}
+
+	/**
+	 * Checks the path information to match the prefixs in
+	 * ICalTokenGenerator.ICAL_PREFIX_COLLECTION
+	 * 
+	 * @param icalFeedPath
+	 * @return boolean
+	 */
+	private boolean checkPath(String icalFeedPath) {
+		// pathInfo is like:
+		// /user/<user_name>/AUTH_TOKEN.ics
+		// /group/<user_name>/AUTH_TOKEN/<group_id>.ics
+		// /course/<user_name>/AUTH_TOKEN/<course_unique_id>.ics
+
+		// check the type of calendar
+		boolean calendarTypeMatched = false;
+		for (int prefixIndex = 0; prefixIndex < ICalTokenGenerator.ICAL_PREFIX_COLLECTION.length; prefixIndex++) {
+			if (icalFeedPath.indexOf(ICalTokenGenerator.ICAL_PREFIX_COLLECTION[prefixIndex]) == 0) {
+				calendarTypeMatched = true;
+			}
+		}
+		if (calendarTypeMatched) {
+			// check the number of tokens in the icalFeedPath
+			int numberOfTokens = icalFeedPath.split("/").length - ICalTokenGenerator.ICAL_PATH_SHIFT;
+			if (isRequestForPersonalCalendarFeed(icalFeedPath)) {
+				return (numberOfTokens == ICalTokenGenerator.ICAL_PERSONAL_PATH_TOKEN_LENGTH);
+			} else {
+				return (numberOfTokens == ICalTokenGenerator.ICAL_PATH_TOKEN_LENGTH);
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * checks whether the iCal feed request is for a personal calendar
+	 * 
+	 * @param icalFeedPath
+	 * @return boolean
+	 */
+	private boolean isRequestForPersonalCalendarFeed(String icalFeedPath) {
+		if (icalFeedPath.indexOf(ICalTokenGenerator.ICAL_PREFIX_PERSONAL) != 0) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+  
+	/**
+	 * Reads in the appropriate ics file, depending upon the pathInfo
+	 * 
+	 * @param pathInfo
+	 * @return Calendar
+	 */
+	private Calendar getIcalDocument(String pathInfo) {
+		// pathInfo is like:
+		// /user/<user_name>/AUTH_TOKEN.ics
+		// /group/<user_name>/AUTH_TOKEN/<group_id>.ics
+		// /course/<user_name>/AUTH_TOKEN/<course_unique_id>.ics
+
+		// get the individual path tokens
+		pathInfo = pathInfo.replaceAll(".ics", "");
+		String[] pathInfoTokens = pathInfo.split("/");
+		String calendarType = pathInfoTokens[0 + ICalTokenGenerator.ICAL_PATH_SHIFT];
+		String userName = pathInfoTokens[1 + ICalTokenGenerator.ICAL_PATH_SHIFT];
+		String authToken = pathInfoTokens[2 + ICalTokenGenerator.ICAL_PATH_SHIFT];
+		String calendarID = userName;
+		if (!isRequestForPersonalCalendarFeed(pathInfo)) {
+			calendarID = pathInfoTokens[3 + ICalTokenGenerator.ICAL_PATH_SHIFT];
+		}
+
+		// check the authentication token
+		if (!checkPathAuthenticity(calendarType, userName, authToken, calendarID)) {
+			log.warn("Authenticity Check failed for the ical feed path: " + pathInfo);
+			return null;
+		}
+
+		CalendarManager calendarManager = CalendarManagerFactory.getInstance().getCalendarManager();
+
+		// check if the calendar exists (calendars are only persisted when an
+		// event is created)
+		if (calendarManager.calendarExists(calendarType, calendarID)) {
+			// read and return the calendar file
+			Calendar calendar = calendarManager.readCalendar(calendarType, calendarID);
+			updateUrlProperties(calendar);
+			return calendar;
+		} else {
+			// return an empty calendar file
+			return new Calendar();
+		}
+	}
+	
+	private void updateUrlProperties(Calendar calendar) {
+		for (Iterator<?> eventIter = calendar.getComponents().iterator(); eventIter.hasNext();) {
+			Object comp = eventIter.next();
+			if (comp instanceof VEvent) {
+				VEvent event = (VEvent)comp;
+				
+				PropertyList ooLinkProperties = event.getProperties(CalendarManager.ICAL_X_OLAT_LINK);
+				if(ooLinkProperties.isEmpty()) {
+					continue;
+				}
+				
+				Url currentUrl = event.getUrl();
+				if(currentUrl != null) {
+					continue;
+				}
+				
+				for (Iterator<?> iter = ooLinkProperties.iterator(); iter.hasNext();) {
+					XProperty linkProperty = (XProperty) iter.next();
+					if (linkProperty != null) {
+						String encodedLink = linkProperty.getValue();
+						StringTokenizer st = new StringTokenizer(encodedLink, "§", false);
+						if (st.countTokens() >= 4) {
+							st.nextToken();//provider
+							st.nextToken();//id
+							st.nextToken();//displayname
+							
+							String uri = st.nextToken();
+							try {
+								Url urlProperty = new Url();
+								urlProperty.setValue(uri);
+								event.getProperties().add(urlProperty);
+								break;
+							} catch (URISyntaxException e) {
+								log.error("Invalid URL:" + uri);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * checks the AUTH_TOKEN in the iCal feed path
+	 * 
+	 * @param type Type of calendar, i.e. User, Group or Course
+	 * @param userName Name of the User
+	 * @param authToken Authentication token for the calendar
+	 * @param icsFileName Name of the ics file
+	 * @return boolean
+	 */
+	private boolean checkPathAuthenticity(String calendarType, String userName, String authToken, String calendarID) {
+		// get the authentication token stored in the database
+		String authTokenFromDb = ICalTokenGenerator.getIcalAuthToken(calendarType, calendarID, userName, false);
+		// check if the token from db matches the token in the url
+		if (authTokenFromDb == null) {
+			return false;
+		} else {
+			return authTokenFromDb.equals(authToken);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/commons/servlets/ICalServlet.java b/src/main/java/org/olat/commons/servlets/ICalServlet.java
deleted file mode 100644
index 59928fc40ecc98a35c268f4e3f7ce831ee62333c..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/commons/servlets/ICalServlet.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
-* OLAT - Online Learning and Training<br>
-* http://www.olat.org
-* <p>
-* Licensed under the Apache License, Version 2.0 (the "License"); <br>
-* you may not use this file except in compliance with the License.<br>
-* You may obtain a copy of the License at
-* <p>
-* http://www.apache.org/licenses/LICENSE-2.0
-* <p>
-* Unless required by applicable law or agreed to in writing,<br>
-* software distributed under the License is distributed on an "AS IS" BASIS, <br>
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
-* See the License for the specific language governing permissions and <br>
-* limitations under the License.
-* <p>
-* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
-* University of Zurich, Switzerland.
-* <hr>
-* <a href="http://www.openolat.org">
-* OpenOLAT - Online Learning and Training</a><br>
-* This file has been modified by the OpenOLAT community. Changes are licensed
-* under the Apache 2.0 license as the original file.  
-* <p>
-*/ 
-
-package org.olat.commons.servlets;
-
-import java.io.IOException;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import net.fortuna.ical4j.data.CalendarOutputter;
-import net.fortuna.ical4j.model.Calendar;
-import net.fortuna.ical4j.model.ValidationException;
-
-import org.apache.poi.util.IOUtils;
-import org.olat.commons.calendar.CalendarManager;
-import org.olat.commons.calendar.CalendarManagerFactory;
-import org.olat.commons.calendar.ICalTokenGenerator;
-import org.olat.core.commons.persistence.DBFactory;
-import org.olat.core.dispatcher.DispatcherModule;
-import org.olat.core.logging.OLog;
-import org.olat.core.logging.Tracing;
-import org.olat.core.util.i18n.I18nManager;
-
-
-/**
- * Description:<BR>
- * Servlet that serves the ical document.
- * <P>
- * Initial Date:  June 1, 2008
- *
- * @author Udit Sajjanhar
- */
-public class ICalServlet extends HttpServlet {
-
-	private static final long serialVersionUID = -155266285395912535L;
-	private static final OLog log = Tracing.createLoggerFor(ICalServlet.class);
-	private static int outputBufferSize = 2048;
-	private static int inputBufferSize = 2048;
-
-	/**
-	 * Default constructor.
-	 */
-	public ICalServlet() {
-	}
-
-	/**
-	 * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
-	 */
-	public void init(ServletConfig servletConfig) throws ServletException {
-		super.init(servletConfig);
-		log.info("init statics servlet");
-		try {
-			String bufSize = servletConfig.getInitParameter("input");
-			inputBufferSize = Integer.parseInt(bufSize);
-			bufSize = servletConfig.getInitParameter("output");
-			inputBufferSize = Integer.parseInt(bufSize);
-		} catch (Exception e) {
-			log.warn("problem with config parameters for ical servlets:", e);
-		}
-		log.info("input buffer size: " + inputBufferSize);
-		log.info("output buffer size: " + inputBufferSize);
-	}
-
-	/**
-	 * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
-	 */
-	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-		Tracing.setUreq(req);
-		String method = req.getMethod();
-		try {
-		if (method.equals("GET")) {
-			doGet(req, resp);
-		} else {
-			super.service(req, resp);
-		}
-		}finally {
-			//consume the userrequest.
-			Tracing.setUreq(null);
-			I18nManager.remove18nInfoFromThread();
-		}
-	}
-
-	/**
-	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
-	 */
-	protected void doGet(HttpServletRequest request, HttpServletResponse response) {
-		Calendar icalDoc = null;
-		
-		ServletOutputStream ostream = null;
-		final boolean debug = log.isDebug();
-		try {
-			String pathInfo = request.getPathInfo();
-			if(debug) log.debug("doGet pathInfo=" + pathInfo);
-			if ((pathInfo == null) || (pathInfo.equals(""))) { 
-				return; // error
-			}
-	
-			if (checkPath(pathInfo)) {
-				icalDoc = getIcalDocument(pathInfo);
-				if (icalDoc == null) {
-					DispatcherModule.sendNotFound(pathInfo, response);
-					return;
-				}
-			} else {
-				DispatcherModule.sendNotFound(pathInfo, response);
-				return;
-			}
-			
-			// OLAT-5243 related: sending back the reply can take arbitrary long,
-			// considering slow end-user connections for example - or a sudden death of the connection
-			// on the client-side which remains unnoticed (network partitioning)
-			DBFactory.getInstance().intermediateCommit();
-			
-      // get the output stream 
-			response.setBufferSize(outputBufferSize);
-			ostream = response.getOutputStream();
-
-      // output the calendar to the stream
-      CalendarOutputter calOut = new CalendarOutputter(false);
-			calOut.output(icalDoc, ostream);
-		} catch (ValidationException e) {
-			// throw olat exception for nice logging
-			log.warn("Validation Error when generate iCal stream for path::" + request.getPathInfo(), e);
-			DispatcherModule.sendNotFound("none", response);
-		} catch (IOException e) {
-			// throw olat exception for nice logging
-			log.warn("IOException Error when generate iCal stream for path::" + request.getPathInfo(), e);
-			DispatcherModule.sendNotFound("none", response);
-		} catch (Exception e) {
-			log.warn("Unknown Error in icalservlet", e);
-			DispatcherModule.sendNotFound("none", response);
-		} finally {
-			IOUtils.closeQuietly(ostream);
-			DBFactory.getInstance(false).commitAndCloseSession();
-		}
-	}
-
-  /**
-   * Checks the path information to match the prefixs in ICalTokenGenerator.ICAL_PREFIX_COLLECTION
-   * @param icalFeedPath
-   * @return boolean
-   */
-  private boolean checkPath(String icalFeedPath) {
-	  // pathInfo is like /user/<user_name>/AUTH_TOKEN.ics
-    //                  /group/<user_name>/AUTH_TOKEN/<group_id>.ics
-    //                  /course/<user_name>/AUTH_TOKEN/<course_unique_id>.ics
-
-  	// check the type of calendar
-  	boolean calendarTypeMatched = false;
-    for (int prefixIndex  = 0; prefixIndex < ICalTokenGenerator.ICAL_PREFIX_COLLECTION.length; prefixIndex++) {
-      if (icalFeedPath.indexOf(ICalTokenGenerator.ICAL_PREFIX_COLLECTION[prefixIndex]) == 0) {
-        calendarTypeMatched = true;
-      }
-    }
-    if (!calendarTypeMatched) {
-    	return false;
-    }
-    
-    // check the number of tokens in the icalFeedPath
-    int numberOfTokens = icalFeedPath.split("/").length - ICalTokenGenerator.ICAL_PATH_SHIFT;
-    if (isRequestForPersonalCalendarFeed(icalFeedPath)) {
-    	return (numberOfTokens == ICalTokenGenerator.ICAL_PERSONAL_PATH_TOKEN_LENGTH);
-    } else { 
-    	return (numberOfTokens == ICalTokenGenerator.ICAL_PATH_TOKEN_LENGTH);
-    }
-  }
-
-  /** 
-   * checks whether the iCal feed request is for a personal calendar
-   * @param  icalFeedPath
-   * @return boolean
-   */
-  private boolean isRequestForPersonalCalendarFeed(String icalFeedPath) {
-  	if (icalFeedPath.indexOf(ICalTokenGenerator.ICAL_PREFIX_PERSONAL) != 0) {
-      return false;
-    } else {
-    	return true;
-    }
-  }
-  
-  /**
-   * Reads in the appropriate ics file, depending upon the pathInfo 
-   * @param pathInfo
-   * @return Calendar
-   */
-  private Calendar getIcalDocument(String pathInfo) {
-	  // pathInfo is like /user/<user_name>/AUTH_TOKEN.ics
-    //                  /group/<user_name>/AUTH_TOKEN/<group_id>.ics
-    //                  /course/<user_name>/AUTH_TOKEN/<course_unique_id>.ics
-
-    // get the individual path tokens
-  	pathInfo = pathInfo.replaceAll(".ics", "");
-    String[] pathInfoTokens = pathInfo.split("/");
-    String calendarType = pathInfoTokens[0 + ICalTokenGenerator.ICAL_PATH_SHIFT];
-    String userName = pathInfoTokens[1 + ICalTokenGenerator.ICAL_PATH_SHIFT];
-    String authToken = pathInfoTokens[2 + ICalTokenGenerator.ICAL_PATH_SHIFT];
-    String calendarID = userName;
-    if (!isRequestForPersonalCalendarFeed(pathInfo)) {
-    	calendarID = pathInfoTokens[3 + ICalTokenGenerator.ICAL_PATH_SHIFT];
-    }
-    
-    // check the authentication token
-    if (!checkPathAuthenticity(calendarType, userName, authToken, calendarID)) {
-  		log.warn("Authenticity Check failed for the ical feed path: " + pathInfo);
-      return null;
-    }
-
-    CalendarManager calendarManager = CalendarManagerFactory.getInstance().getCalendarManager();
-    
-    // check if the calendar exists (calendars are only persisted when an event is created)
-    if (calendarManager.calendarExists(calendarType, calendarID)) {
-    	// read and return the calendar file
-    	return calendarManager.readCalendar(calendarType, calendarID);
-    } else {
-    	// return an empty calendar file
-    	return new Calendar();
-    }
-    	
-    
-  }
-
-  /**
-   * checks the AUTH_TOKEN in the iCal feed path
-   * @param type Type of calendar, i.e. User, Group or Course
-   * @param userName Name of the User
-   * @param authToken Authentication token for the calendar
-   * @param icsFileName Name of the ics file
-   * @return boolean
-   */
-  private boolean checkPathAuthenticity(String calendarType, String userName, String authToken, String calendarID) {
-
-  	// get the authentication token stored in the database
-  	String authTokenFromDb = ICalTokenGenerator.getIcalAuthToken(calendarType, calendarID, userName, false);
-  	
-  	// check if the token from db matches the token in the url
-  	if (authTokenFromDb == null) {
-  		return false;
-  	} else {
-  		return authTokenFromDb.equals(authToken);
-  	}
-  }
-  
-}
diff --git a/src/main/webapp-tomcat/WEB-INF/web.xml b/src/main/webapp-tomcat/WEB-INF/web.xml
index 842a692ca156da1d86eab1f3140567c7b0a7e2f4..3c2e1eded83b6f7e4b00eb59405f28854367d9dc 100644
--- a/src/main/webapp-tomcat/WEB-INF/web.xml
+++ b/src/main/webapp-tomcat/WEB-INF/web.xml
@@ -212,20 +212,9 @@
 	<!-- ICAL feed requests -->
 	<servlet>
 		<servlet-name>ical</servlet-name>
-		<servlet-class>org.olat.commons.servlets.ICalServlet</servlet-class>
-
-		<init-param>
-			<param-name>input</param-name>
-			<param-value>32768</param-value>
-		</init-param>
-
-		<init-param>
-			<param-name>output</param-name>
-			<param-value>32768</param-value>
-		</init-param>
-
+		<servlet-class>org.olat.commons.calendar.ICalServlet</servlet-class>
 		<load-on-startup>3</load-on-startup>
-  </servlet>	
+	</servlet>	
 
 	<!-- 5.Servlet-Mapping -->
 	<!-- The mapping for the OLAT servlet -->
diff --git a/src/main/webapp-wildfly/WEB-INF/web.xml b/src/main/webapp-wildfly/WEB-INF/web.xml
index 4093350caeb2c12d3e3f9f19648af7f5a5d3c8dd..ce84ffcce0eaa82d947abdd0f84a2c51f6729083 100644
--- a/src/main/webapp-wildfly/WEB-INF/web.xml
+++ b/src/main/webapp-wildfly/WEB-INF/web.xml
@@ -159,20 +159,9 @@
 	<!-- ICAL feed requests -->
 	<servlet>
 		<servlet-name>ical</servlet-name>
-		<servlet-class>org.olat.commons.servlets.ICalServlet</servlet-class>
-
-		<init-param>
-			<param-name>input</param-name>
-			<param-value>32768</param-value>
-		</init-param>
-
-		<init-param>
-			<param-name>output</param-name>
-			<param-value>32768</param-value>
-		</init-param>
-
+		<servlet-class>org.olat.commons.calendar.ICalServlet</servlet-class>
 		<load-on-startup>3</load-on-startup>
-  </servlet>	
+	</servlet>	
 
 	<!-- 5.Servlet-Mapping -->
 	<!-- The mapping for the OLAT servlet -->