diff --git a/src/main/java/org/olat/course/nodes/BigBlueButtonCourseNode.java b/src/main/java/org/olat/course/nodes/BigBlueButtonCourseNode.java
index b8d5af91ede6b011deb5ddc04e39856ce55ba2a1..8a2cc327697297b288adf4a1473f5c63eaa5c331 100644
--- a/src/main/java/org/olat/course/nodes/BigBlueButtonCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/BigBlueButtonCourseNode.java
@@ -39,6 +39,7 @@ import org.olat.course.editor.NodeEditController;
 import org.olat.course.editor.StatusDescription;
 import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.nodes.bigbluebutton.BigBlueButtonEditController;
+import org.olat.course.nodes.bigbluebutton.BigBlueButtonPeekViewController;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
@@ -115,6 +116,12 @@ public class BigBlueButtonCourseNode extends AbstractAccessableCourseNode {
 		return new NodeRunConstructionResult(ctrl);
 	}
 	
+	@Override
+	public Controller createPeekViewRunController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv,
+			NodeEvaluation ne) {
+		return new BigBlueButtonPeekViewController(ureq, wControl, userCourseEnv.getCourseEnvironment(), this);
+	}
+	
 	@Override
 	public StatusDescription isConfigValid() {
 		if (oneClickStatusCache != null) { return oneClickStatusCache[0]; }
diff --git a/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonConfigForm.java b/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonConfigForm.java
index 2dadf712c0537ade225386ed7a2e708cea550829..8b50b719ca72d56781cd62c7b1abd58102b9e6e6 100644
--- a/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonConfigForm.java
+++ b/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonConfigForm.java
@@ -75,8 +75,7 @@ public class BigBlueButtonConfigForm extends FormBasicController {
 	@Override
 	protected void formOK(UserRequest ureq) {
 		Collection<String> selectedKeys = accessEl.getSelectedKeys();
-		config.setBooleanEntry(BigBlueButtonEditController.ACCESS_BY_DATES, selectedKeys.contains(accessKeys[0]));
-		config.setBooleanEntry(BigBlueButtonEditController.GUEST_ACCESS_ALLOWED, !selectedKeys.contains(accessKeys[1]));
+		config.setBooleanEntry(BigBlueButtonEditController.MODERATOR_START_MEETING, !selectedKeys.contains(accessKeys[0]));
 		fireEvent(ureq, NodeEditController.NODECONFIG_CHANGED_EVENT);
 	}
 }
diff --git a/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonPeekViewController.java b/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonPeekViewController.java
index 310ab4e0083eae3e248d9f817bf9ec4025923093..1b4c00c092a5261c2833345d19d153e318f2b4a4 100644
--- a/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonPeekViewController.java
+++ b/src/main/java/org/olat/course/nodes/bigbluebutton/BigBlueButtonPeekViewController.java
@@ -19,11 +19,29 @@
  */
 package org.olat.course.nodes.bigbluebutton;
 
+import java.util.List;
+
+import org.olat.core.commons.persistence.SortKey;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
+import org.olat.core.gui.components.form.flexible.elements.FlexiTableSortOptions;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.util.Util;
+import org.olat.course.nodes.BigBlueButtonCourseNode;
+import org.olat.course.run.environment.CourseEnvironment;
+import org.olat.modules.bigbluebutton.BigBlueButtonManager;
+import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.ui.BigBlueButtonMeetingTableModel;
+import org.olat.modules.bigbluebutton.ui.BigBlueButtonMeetingTableModel.BMeetingsCols;
+import org.olat.modules.bigbluebutton.ui.BigBlueButtonRunController;
+import org.olat.repository.RepositoryEntry;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
@@ -32,16 +50,48 @@ import org.olat.core.gui.control.WindowControl;
  *
  */
 public class BigBlueButtonPeekViewController extends FormBasicController {
+	
+	private FlexiTableElement upcomingTableEl;
+	private BigBlueButtonMeetingTableModel upcomingTableModel;
 
-	public BigBlueButtonPeekViewController(UserRequest ureq, WindowControl wControl) {
-		super(ureq, wControl);
+	private final String subIdent;
+	private final RepositoryEntry courseEntry;
+	
+	@Autowired
+	private BigBlueButtonManager bigBlueButtonManager;
+
+	public BigBlueButtonPeekViewController(UserRequest ureq, WindowControl wControl,
+			CourseEnvironment courseEnv, BigBlueButtonCourseNode courseNode) {
+		super(ureq, wControl, "peekview", Util.createPackageTranslator(BigBlueButtonRunController.class, ureq.getLocale()));
+		courseEntry = courseEnv.getCourseGroupManager().getCourseEntry();
+		subIdent = courseNode.getIdent();
 		
 		initForm(ureq);
+		loadModel();
 	}
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
-		//
+		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.name));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.start));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.end));
+
+		upcomingTableModel = new BigBlueButtonMeetingTableModel(columnsModel, getLocale());
+		upcomingTableEl = uifactory.addTableElement(getWindowControl(), "upcomingMeetings", upcomingTableModel,
+				5, false, getTranslator(), formLayout);
+		upcomingTableEl.setEmtpyTableMessageKey("no.upcoming.meetings");
+		upcomingTableEl.setCustomizeColumns(false);
+		upcomingTableEl.setNumOfRowsEnabled(false);
+		
+		FlexiTableSortOptions sortOptions = new FlexiTableSortOptions();
+		sortOptions.setDefaultOrderBy(new SortKey(BMeetingsCols.start.name(), true));
+		upcomingTableEl.setSortSettings(sortOptions);
+	}
+	
+	private void loadModel() {
+		List<BigBlueButtonMeeting> meetings = bigBlueButtonManager.getUpcomingsMeetings(courseEntry, subIdent, 5);
+		upcomingTableModel.setObjects(meetings);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/course/nodes/bigbluebutton/_content/peekview.html b/src/main/java/org/olat/course/nodes/bigbluebutton/_content/peekview.html
new file mode 100644
index 0000000000000000000000000000000000000000..40b7a437fab36c731aa1b307d4ad02c0a3fc927b
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/bigbluebutton/_content/peekview.html
@@ -0,0 +1 @@
+$r.render("upcomingMeetings")
diff --git a/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonManager.java b/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonManager.java
index 2f417ea429abdb57c822c52e83c1142ae22f331f..b7c32977de863359b373e92564b1fa5a3604f78d 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonManager.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonManager.java
@@ -19,12 +19,14 @@
  */
 package org.olat.modules.bigbluebutton;
 
+import java.util.Date;
 import java.util.List;
 
 import org.olat.core.id.Identity;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.bigbluebutton.model.BigBlueButtonErrors;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryRef;
 
 /**
  * 
@@ -45,6 +47,18 @@ public interface BigBlueButtonManager {
 	 * @return A meeting with some default values
 	 */
 	public BigBlueButtonMeeting createAndPersistMeeting(String name, RepositoryEntry entry, String subIdent, BusinessGroup businessGroup);
+	
+	/**
+	 * Is there a server available.
+	 * 
+	 * @param template The selected template
+	 * @param start Start date
+	 * @param leadTime Lead time
+	 * @param end End date
+	 * @param followupTime Follow-up time
+	 * @return true if the meeting can be reserved
+	 */
+	public boolean isSlotAvailable(BigBlueButtonMeetingTemplate template, Date start, long leadTime, Date end, long followupTime);
 
 	public BigBlueButtonMeeting getMeeting(BigBlueButtonMeeting meeting);
 	
@@ -62,9 +76,17 @@ public interface BigBlueButtonManager {
 	
 	public boolean isTemplateInUse(BigBlueButtonMeetingTemplate template);
 	
-	public List<BigBlueButtonMeeting> getMeetings(RepositoryEntry entry, String subIdent, BusinessGroup businessGroup);
+	public List<BigBlueButtonMeeting> getMeetings(RepositoryEntryRef entry, String subIdent, BusinessGroup businessGroup);
+	
+	/**
+	 * Return the list of upcoming meetings, without any permanent one.
+	 * 
+	 * @param entry The course / resource entry
+	 * @param subIdent The sub identifier
+	 * @return
+	 */
+	public List<BigBlueButtonMeeting> getUpcomingsMeetings(RepositoryEntryRef entry, String subIdent, int maxResults);
 	
-
 	public List<BigBlueButtonMeeting> getAllMeetings();
 	
 	public String join(BigBlueButtonMeeting meeting, Identity identity, boolean moderator, boolean guest, BigBlueButtonErrors errors);
diff --git a/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonMeetingTemplate.java b/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonMeetingTemplate.java
index d1b3edff0973a37a7cae478c342c2c7b9fde0f07..7e3f5f72bcf68e954486acd8200a1210e0e2e488 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonMeetingTemplate.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonMeetingTemplate.java
@@ -44,6 +44,10 @@ public interface BigBlueButtonMeetingTemplate extends ModifiedInfo, CreateInfo {
 
 	public void setDescription(String description);
 	
+	public Integer getMaxConcurrentMeetings();
+
+	public void setMaxConcurrentMeetings(Integer maxConcurrentMeetings);
+	
 	public Integer getMaxParticipants();
 
 	public void setMaxParticipants(Integer maxParticipants);
diff --git a/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonModule.java b/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonModule.java
index 157865ab7725b6193e0c89ce543cc8bb91ac2ab2..232c98d797bebed04793a6b84252f48e18fda00d 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonModule.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/BigBlueButtonModule.java
@@ -51,6 +51,9 @@ public class BigBlueButtonModule extends AbstractSpringModule implements ConfigO
 	private static final String PROP_PORT = "vc.bigbluebutton.port";
 	private static final String PROP_BASEURL = "vc.bigbluebutton.baseurl";
 	private static final String PROP_CONTEXTPATH = "vc.bigbluebutton.contextpath";
+	private static final String PROP_PERMANENT_MEETING = "vc.bigbluebutton.permanent.meeting";
+	private static final String PROP_ADHOC_MEETING = "vc.bigbluebutton.adhoc.meeting";
+	private static final String PROP_USER_BANDWIDTH_REQUIREMENT = "vc.bigbluebutton.user.bandwidth.requirement";
 	
 	@Value("${vc.bigbluebutton.enabled}")
 	private boolean enabled;
@@ -77,6 +80,13 @@ public class BigBlueButtonModule extends AbstractSpringModule implements ConfigO
 	@Value("${vc.bigbluebutton.shared.secret}")
 	private String sharedSecret;
 	
+	@Value("${vc.bigbluebutton.permanent.meeting:false}")
+	private String permanentMeetingEnabled;
+	@Value("${vc.bigbluebutton.adhoc.meeting:true}")
+	private String adhocMeetingEnabled;
+	@Value("${vc.bigbluebutton.user.bandwidth.requirement:0.4}")
+	private Double userBandwidhtRequirement;
+	
 	
 	@Autowired
 	public BigBlueButtonModule(CoordinatorManager coordinatorManager) {
@@ -101,6 +111,11 @@ public class BigBlueButtonModule extends AbstractSpringModule implements ConfigO
 		daysToKeep = getStringPropertyValue(PROP_DAYS_TO_KEEP, daysToKeep);
 		secret = getStringPropertyValue(PROP_SECRET, secret);
 		sharedSecret = getStringPropertyValue(PROP_SHARED_SECRET, sharedSecret);
+		
+		String bandwidthReqObj = getStringPropertyValue(PROP_USER_BANDWIDTH_REQUIREMENT, true);
+		if(StringHelper.containsNonWhitespace(bandwidthReqObj)) {
+			userBandwidhtRequirement = Double.parseDouble(bandwidthReqObj);
+		}
 	}
 	
 	@Override
@@ -267,4 +282,30 @@ public class BigBlueButtonModule extends AbstractSpringModule implements ConfigO
 		
 	}
 
+	public Double getUserBandwidhtRequirement() {
+		return userBandwidhtRequirement;
+	}
+
+	public void setUserBandwidhtRequirement(Double userBandwidhtRequirement) {
+		this.userBandwidhtRequirement = userBandwidhtRequirement;
+		setStringProperty(PROP_USER_BANDWIDTH_REQUIREMENT, userBandwidhtRequirement.toString(), true);
+	}
+
+	public boolean isPermanentMeetingEnabled() {
+		return "true".equals(permanentMeetingEnabled);
+	}
+
+	public void setPermanentMeetingEnabled(boolean permanentMeetingEnabled) {
+		this.permanentMeetingEnabled = Boolean.toString(permanentMeetingEnabled);
+		setStringProperty(PROP_PERMANENT_MEETING, this.permanentMeetingEnabled, true);
+	}
+
+	public boolean isAdhocMeetingEnabled() {
+		return "true".equals(adhocMeetingEnabled);
+	}
+
+	public void setAdhocMeetingEnabled(boolean adhocMeetingEnabled) {
+		this.adhocMeetingEnabled = Boolean.toString(adhocMeetingEnabled);
+		setStringProperty(PROP_ADHOC_MEETING, this.adhocMeetingEnabled, true);
+	}	
 }
diff --git a/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonManagerImpl.java b/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonManagerImpl.java
index 8d6a29d7bb0ede5676a18f2c06652ed5f8ffcbcf..40bddc823c2dd5ebed4886bc6e4043fb98055d86 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonManagerImpl.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonManagerImpl.java
@@ -20,6 +20,7 @@
 package org.olat.modules.bigbluebutton.manager;
 
 import java.net.URI;
+import java.util.Date;
 import java.util.List;
 
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -51,6 +52,7 @@ import org.olat.modules.bigbluebutton.model.BigBlueButtonError;
 import org.olat.modules.bigbluebutton.model.BigBlueButtonErrorCodes;
 import org.olat.modules.bigbluebutton.model.BigBlueButtonErrors;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.manager.RepositoryEntryDAO;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -84,32 +86,32 @@ public class BigBlueButtonManagerImpl implements BigBlueButtonManager, Initializ
 		List<BigBlueButtonMeetingTemplate> templates = bigBlueButtonMeetingTemplateDao.getTemplates();
 		
 		// Web conferen
-		defaultTemplate("web-conference", "Web conference", 100,
+		defaultTemplate("sys-meetings", "Meetings", 5, 5,
 				Boolean.FALSE, Boolean.FALSE, Boolean.TRUE, // recording
-				Boolean.TRUE, Boolean.TRUE, // webcams, unmute
-				Boolean.TRUE, Boolean.TRUE, // cam, mic
+				Boolean.FALSE, Boolean.TRUE, // webcams moderator only, unmute
+				Boolean.FALSE, Boolean.FALSE, // cam, mic
 				Boolean.FALSE, Boolean.TRUE, // chat
 				Boolean.FALSE, Boolean.FALSE, // node, layout
-				GuestPolicyEnum.ALWAYS_ACCEPT, templates);
+				GuestPolicyEnum.ALWAYS_DENY, templates);
 		
-		defaultTemplate("web-classe", "Classes / Klasse", 25,
+		defaultTemplate("sys-classes", "Classes", 20, 30,
 				Boolean.FALSE, Boolean.FALSE, Boolean.TRUE, // recording
-				Boolean.FALSE, Boolean.TRUE, // webcams, unmute
-				Boolean.FALSE, Boolean.FALSE, // cam, mic
+				Boolean.TRUE, Boolean.TRUE, // webcamsmoderator only, unmute
+				Boolean.TRUE, Boolean.TRUE, // cam, mic
 				Boolean.FALSE, Boolean.FALSE, // chat
 				Boolean.FALSE, Boolean.FALSE, // node, layout
 				GuestPolicyEnum.ALWAYS_DENY, templates);
 		
-		defaultTemplate("web-one-to-one", "One to one", 2,
+		defaultTemplate("sys-cafe", "Cafe", 10, 10,
 				Boolean.FALSE, Boolean.FALSE, Boolean.TRUE, // recording
-				Boolean.FALSE, Boolean.TRUE, // webcams, unmute
+				Boolean.FALSE, Boolean.TRUE, // webcams moderator only, unmute
 				Boolean.FALSE, Boolean.FALSE, // cam, mic
 				Boolean.TRUE, Boolean.FALSE, // chat
 				Boolean.FALSE, Boolean.FALSE, // node, layout
 				GuestPolicyEnum.ALWAYS_DENY, templates);
 	}
 	
-	private void defaultTemplate(String externalId, String name, Integer maxParticipants,
+	private void defaultTemplate(String externalId, String name, Integer maxConcurrentMeetings, Integer maxParticipants,
 			Boolean muteOnStart, Boolean autoStartRecording, Boolean allowStartStopRecording,
 			Boolean webcamsOnlyForModerator, Boolean allowModsToUnmuteUsers,
 			Boolean lockSettingsDisableCam, Boolean lockSettingsDisableMic,
@@ -120,9 +122,12 @@ public class BigBlueButtonManagerImpl implements BigBlueButtonManager, Initializ
 		BigBlueButtonMeetingTemplate template = templates.stream()
 				.filter(tpl -> externalId.equals(tpl.getExternalId()))
 				.findFirst().orElse(null);
-		if(template == null) {
-			template = bigBlueButtonMeetingTemplateDao.createTemplate(name, externalId, true);
+		if(template != null) {
+			return;
 		}
+		
+		template = bigBlueButtonMeetingTemplateDao.createTemplate(name, externalId, true);
+		template.setMaxConcurrentMeetings(maxConcurrentMeetings);
 		template.setMaxParticipants(maxParticipants);
 		template.setMuteOnStart(muteOnStart);
 		template.setAutoStartRecording(autoStartRecording);
@@ -144,6 +149,18 @@ public class BigBlueButtonManagerImpl implements BigBlueButtonManager, Initializ
 		return bigBlueButtonMeetingDao.createAndPersistMeeting(name, entry, subIdent, businessGroup);
 	}
 	
+	@Override
+	public boolean isSlotAvailable(BigBlueButtonMeetingTemplate template, Date startDate, long leadTime, Date endDate, long followupTime) {
+		if(template == null) return false; // template are mandatory
+		if(template.getMaxConcurrentMeetings() == null) {
+			return true;
+		}
+		Date start = bigBlueButtonMeetingDao.calculateStartWithLeadTime(startDate, leadTime);
+		Date end = bigBlueButtonMeetingDao.calculateEndWithFollowupTime(endDate, followupTime);
+		int numOfCurrentMeetings = bigBlueButtonMeetingDao.getConcurrentMeetings(template, start, end);
+		return numOfCurrentMeetings < template.getMaxConcurrentMeetings().intValue();
+	}
+
 	@Override
 	public BigBlueButtonMeeting getMeeting(BigBlueButtonMeeting meeting) {
 		return bigBlueButtonMeetingDao.loadByKey(meeting.getKey());
@@ -186,10 +203,15 @@ public class BigBlueButtonManagerImpl implements BigBlueButtonManager, Initializ
 	}
 
 	@Override
-	public List<BigBlueButtonMeeting> getMeetings(RepositoryEntry entry, String subIdent, BusinessGroup businessGroup) {
+	public List<BigBlueButtonMeeting> getMeetings(RepositoryEntryRef entry, String subIdent, BusinessGroup businessGroup) {
 		return bigBlueButtonMeetingDao.getMeetings(entry, subIdent, businessGroup);
 	}
 	
+	@Override
+	public List<BigBlueButtonMeeting> getUpcomingsMeetings(RepositoryEntryRef entry, String subIdent, int maxResults) {
+		return bigBlueButtonMeetingDao.getUpcomingMeetings(entry, subIdent, maxResults);
+	}
+	
 	@Override
 	public boolean deleteMeeting(BigBlueButtonMeeting meeting, BigBlueButtonErrors errors) {
 		BigBlueButtonMeeting reloadedMeeting = bigBlueButtonMeetingDao.loadByKey(meeting.getKey());
@@ -346,10 +368,11 @@ public class BigBlueButtonManagerImpl implements BigBlueButtonManager, Initializ
 			.optionalParameter("moderatorPW", meeting.getModeratorPassword())
 			.optionalParameter("logoutURL", getBusinessPath(meeting));
 		if(meeting.getStartWithLeadTime() != null && meeting.getEndWithFollowupTime() != null) {
-			long start = meeting.getStartWithLeadTime().getTime();
+			long now = new Date().getTime();
+			long start = Math.max(now, meeting.getStartWithLeadTime().getTime());
 			long end = meeting.getEndWithFollowupTime().getTime();
-			long duration = (end - start) / (60l * 1000l);
-			uriBuilder.optionalParameter("duration", Long.toString(duration + 1));// + 1 for rounding error
+			long duration = 1 + (Math.abs(end - start) / (60l * 1000l));// + 1 to compensate rounding error
+			uriBuilder.optionalParameter("duration", Long.toString(duration));
 		}
 
 		if(template != null) {
@@ -377,6 +400,16 @@ public class BigBlueButtonManagerImpl implements BigBlueButtonManager, Initializ
 		return BigBlueButtonUtils.checkSuccess(doc, errors);
 	}
 	
+	public void getBigBlueButtonDefaultConfigXml() {
+		BigBlueButtonUriBuilder uriBuilder = getUriBuilder();
+		uriBuilder
+			.operation("getDefaultConfigXML");
+		BigBlueButtonErrors errors = new BigBlueButtonErrors();
+		Document doc = sendRequest(uriBuilder, errors);
+		BigBlueButtonUtils.print(doc);
+		BigBlueButtonUtils.checkSuccess(doc, errors);	
+	}
+	
 	@Override
 	public boolean checkConnection(String url, String sharedSecret, BigBlueButtonErrors errors) {
 		BigBlueButtonUriBuilder uriBuilder = BigBlueButtonUriBuilder.fromUri(URI.create(url), sharedSecret);
diff --git a/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAO.java b/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAO.java
index 94540374f495cc98142fe795d4fc650d0abaa3c0..58fbf824e11451a88c505b457ce1e25c1d364bcc 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAO.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAO.java
@@ -31,8 +31,10 @@ import org.olat.core.commons.persistence.QueryBuilder;
 import org.olat.core.util.StringHelper;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.BigBlueButtonMeetingTemplate;
 import org.olat.modules.bigbluebutton.model.BigBlueButtonMeetingImpl;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryRef;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -93,19 +95,14 @@ public class BigBlueButtonMeetingDAO {
 	}
 	
 	private void updateDates(BigBlueButtonMeetingImpl meet, Date start, long leadTime, Date end, long followupTime) {
-		Calendar cal = Calendar.getInstance();
 		if(start == null) {
 			meet.setStartDate(null);
 			meet.setLeadTime(0);
 			meet.setStartWithLeadTime(null);
 		} else {
-			start = cleanDate(start);
-			if(leadTime > 0) {
-				cal.add(Calendar.MINUTE, -(int)leadTime);
-			}
 			meet.setStartDate(start);
 			meet.setLeadTime(leadTime);
-			meet.setStartWithLeadTime(cal.getTime());
+			meet.setStartWithLeadTime(calculateStartWithLeadTime(start, leadTime));
 		}
 		
 		if(end == null) {
@@ -113,15 +110,30 @@ public class BigBlueButtonMeetingDAO {
 			meet.setFollowupTime(0);
 			meet.setEndWithFollowupTime(null);
 		} else {
-			end = cleanDate(end);
-			cal.setTime(end);
-			if(followupTime > 0) {
-				cal.add(Calendar.MINUTE, (int)followupTime);
-			}
 			meet.setEndDate(end);
 			meet.setFollowupTime(followupTime);
-			meet.setEndWithFollowupTime(cal.getTime());
+			meet.setEndWithFollowupTime(calculateEndWithFollowupTime(end, followupTime));
+		}
+	}
+	
+	protected Date calculateStartWithLeadTime(Date start, long leadTime) {
+		start = cleanDate(start);
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(start);
+		if(leadTime > 0) {
+			cal.add(Calendar.MINUTE, -(int)leadTime);
 		}
+		return cal.getTime();
+	}
+	
+	protected Date calculateEndWithFollowupTime(Date end, long followupTime) {
+		end = cleanDate(end);
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(end);
+		if(followupTime > 0) {
+			cal.add(Calendar.MINUTE, (int)followupTime);
+		}
+		return cal.getTime();
 	}
 	
 	/**
@@ -149,7 +161,30 @@ public class BigBlueButtonMeetingDAO {
 				.getResultList();
 	}
 	
-	public List<BigBlueButtonMeeting> getMeetings(RepositoryEntry entry, String subIdent, BusinessGroup businessGroup) {
+	public int getConcurrentMeetings(BigBlueButtonMeetingTemplate template, Date start, Date end) {
+		QueryBuilder sb = new QueryBuilder();
+		sb.append("select count(distinct meeting.key) from bigbluebuttonmeeting as meeting")
+		  .append(" inner join meeting.template as template")
+		  .append(" where template.key=:templateKey")
+		  .append(" and (")
+		  .append("  (meeting.startWithLeadTime>=:startDate and meeting.startWithLeadTime<=:endDate)")
+		  .append("  or")
+		  .append("  (meeting.endWithFollowupTime>=:startDate and meeting.endWithFollowupTime<=:endDate)")
+		  .append("  or")
+		  .append("  (meeting.startWithLeadTime>=:startDate and meeting.endWithFollowupTime<=:endDate)")
+		  .append("  or")
+		  .append("  (meeting.startWithLeadTime<=:startDate and meeting.endWithFollowupTime>=:endDate)")
+		  .append(")");
+		List<Long> count = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Long.class)
+				.setParameter("templateKey", template.getKey())
+				.setParameter("startDate", start)
+				.setParameter("endDate", end)
+				.getResultList();
+		return count == null || count.isEmpty() || count.get(0) == null ? 0 : count.get(0).intValue();
+	}
+	
+	public List<BigBlueButtonMeeting> getMeetings(RepositoryEntryRef entry, String subIdent, BusinessGroup businessGroup) {
 		QueryBuilder sb = new QueryBuilder();
 		sb.append("select meeting from bigbluebuttonmeeting as meeting")
 		  .append(" left join fetch meeting.template as template");
@@ -168,7 +203,6 @@ public class BigBlueButtonMeetingDAO {
 		
 		if(entry != null) {
 			query.setParameter("entryKey", entry.getKey());
-			sb.and().append("meeting.entry.key=:entryKey");
 			if(StringHelper.containsNonWhitespace(subIdent)) {
 				query.setParameter("subIdent", subIdent);
 			}
@@ -178,5 +212,29 @@ public class BigBlueButtonMeetingDAO {
 		}
 		return query.getResultList();
 	}
+	
+	public List<BigBlueButtonMeeting> getUpcomingMeetings(RepositoryEntryRef entry, String subIdent, int maxResults) {
+		QueryBuilder sb = new QueryBuilder();
+		sb.append("select meeting from bigbluebuttonmeeting as meeting")
+		  .append(" left join fetch meeting.template as template")
+		  .append(" where meeting.entry.key=:entryKey and meeting.permanent=false")
+		  .append(" and meeting.startDate is not null and meeting.endDate is not null");
+		if(StringHelper.containsNonWhitespace(subIdent)) {
+			sb.append(" and meeting.subIdent=:subIdent");
+		}
+		sb.append(" and meeting.endDate>=:now")
+		  .append(" order by meeting.startDate asc");
+
+		TypedQuery<BigBlueButtonMeeting> query = dbInstance.getCurrentEntityManager()
+			.createQuery(sb.toString(), BigBlueButtonMeeting.class)
+			.setFirstResult(0)
+			.setMaxResults(maxResults)
+			.setParameter("entryKey", entry.getKey())
+			.setParameter("now", new Date());
+		if(StringHelper.containsNonWhitespace(subIdent)) {
+			query.setParameter("subIdent", subIdent);
+		}
+		return query.getResultList();
+	}
 
 }
diff --git a/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonUtils.java b/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonUtils.java
index e6010d3a5c6f1b7cda9cc9dc190eadda11cf4301..1d45442fac66c3df44c9536d2e83465155b85244 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonUtils.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonUtils.java
@@ -131,5 +131,4 @@ public class BigBlueButtonUtils {
 			}
 		}
 	}
-
 }
diff --git a/src/main/java/org/olat/modules/bigbluebutton/model/BigBlueButtonMeetingTemplateImpl.java b/src/main/java/org/olat/modules/bigbluebutton/model/BigBlueButtonMeetingTemplateImpl.java
index 4c97189530b1c24b220f9e8af36d746d7e79bf29..ccef9cdc0b2fd0201a063f38290e2849dde6e779 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/model/BigBlueButtonMeetingTemplateImpl.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/model/BigBlueButtonMeetingTemplateImpl.java
@@ -68,6 +68,9 @@ public class BigBlueButtonMeetingTemplateImpl implements Persistable, BigBlueBut
 	@Column(name="b_external_id", nullable=true, insertable=true, updatable=true)
 	private String externalId;
 	
+	@Column(name="b_max_concurrent_meetings", nullable=true, insertable=true, updatable=true)
+	private Integer maxConcurrentMeetings;
+	
 	@Column(name="b_max_participants", nullable=true, insertable=true, updatable=true)
 	private Integer maxParticipants;
 
@@ -165,6 +168,16 @@ public class BigBlueButtonMeetingTemplateImpl implements Persistable, BigBlueBut
 		this.externalId = externalId;
 	}
 
+	@Override
+	public Integer getMaxConcurrentMeetings() {
+		return maxConcurrentMeetings;
+	}
+
+	@Override
+	public void setMaxConcurrentMeetings(Integer maxConcurrentMeetings) {
+		this.maxConcurrentMeetings = maxConcurrentMeetings;
+	}
+
 	@Override
 	public Integer getMaxParticipants() {
 		return maxParticipants;
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminController.java
index 868fe75fa4909f1cce432c63e5fdf4ebd3510835..1a94e6f04a2f454e01b8a50adc6719c4faa35257 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminController.java
@@ -33,6 +33,7 @@ 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.gui.control.generic.dtabs.Activateable2;
+import org.olat.core.id.Roles;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
 import org.olat.core.util.resource.OresHelper;
@@ -45,12 +46,14 @@ import org.olat.core.util.resource.OresHelper;
  */
 public class BigBlueButtonAdminController extends BasicController implements Activateable2 {
 	
+	private Link configurationLink;
 	private final Link meetingsLink;
 	private final Link templatesLink;
-	private final Link configurationLink;
 	private final SegmentViewComponent segmentView;
 	private final VelocityContainer mainVC;
 	
+	private final boolean configurationReadOnly;
+	
 	private BigBlueButtonConfigurationController configCtrl;
 	private BigBlueButtonAdminMeetingsController meetingsCtrl;
 	private BigBlueButtonAdminTemplatesController templatesCtrl;
@@ -58,17 +61,27 @@ public class BigBlueButtonAdminController extends BasicController implements Act
 	public BigBlueButtonAdminController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl);
 		
+		Roles roles = ureq.getUserSession().getRoles();
+		configurationReadOnly = !roles.isAdministrator() && !roles.isSystemAdmin();
+		
 		mainVC = createVelocityContainer("bbb_admin");
 		
-		segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
-		configurationLink = LinkFactory.createLink("account.configuration", mainVC, this);
-		segmentView.addSegment(configurationLink, true);
+			segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
+		if(!configurationReadOnly) {
+			configurationLink = LinkFactory.createLink("account.configuration", mainVC, this);
+			segmentView.addSegment(configurationLink, true);
+		}
 		templatesLink = LinkFactory.createLink("templates.title", mainVC, this);
 		segmentView.addSegment(templatesLink, false);
 		meetingsLink = LinkFactory.createLink("meetings.title", mainVC, this);
 		segmentView.addSegment(meetingsLink, false);
 		
-		doOpenConfiguration(ureq);
+		if(configurationReadOnly) {
+			doOpenMeetings(ureq);
+			segmentView.select(meetingsLink);
+		} else {
+			doOpenConfiguration(ureq);
+		}
 		
 		putInitialPanel(mainVC);
 	}
@@ -83,7 +96,7 @@ public class BigBlueButtonAdminController extends BasicController implements Act
 		if(entries == null || entries.isEmpty()) return;
 
 		String type = entries.get(0).getOLATResourceable().getResourceableTypeName();
-		if("Configuration".equalsIgnoreCase(type)) {
+		if("Configuration".equalsIgnoreCase(type) && !configurationReadOnly) {
 			doOpenConfiguration(ureq);
 			segmentView.select(configurationLink);
 		} else if("Templates".equalsIgnoreCase(type)) {
@@ -127,7 +140,7 @@ public class BigBlueButtonAdminController extends BasicController implements Act
 	private void doOpenTemplates(UserRequest ureq) {
 		if(templatesCtrl == null) {
 			WindowControl bwControl = addToHistory(ureq, OresHelper.createOLATResourceableInstance("Templates", 0l), null);
-			templatesCtrl = new BigBlueButtonAdminTemplatesController(ureq, bwControl);
+			templatesCtrl = new BigBlueButtonAdminTemplatesController(ureq, bwControl, configurationReadOnly);
 			listenTo(templatesCtrl);
 		} else {
 			addToHistory(ureq, templatesCtrl);
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminMeetingsController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminMeetingsController.java
index 071ff0065b44c956c6f669c65cf6f1d45e43febd..b7270325c89f07b0755325717113aea96a47f630 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminMeetingsController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminMeetingsController.java
@@ -45,6 +45,7 @@ import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.util.StringHelper;
 import org.olat.modules.bigbluebutton.BigBlueButtonManager;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.BigBlueButtonModule;
 import org.olat.modules.bigbluebutton.model.BigBlueButtonErrors;
 import org.olat.modules.bigbluebutton.ui.BigBlueButtonMeetingTableModel.BMeetingsCols;
 import org.olat.modules.gotomeeting.ui.GoToMeetingTableModel.MeetingsCols;
@@ -62,7 +63,9 @@ public class BigBlueButtonAdminMeetingsController extends FormBasicController {
 	private BigBlueButtonMeetingTableModel tableModel;
 
 	private DialogBoxController confirmDelete;
-	
+
+	@Autowired
+	private BigBlueButtonModule bigBlueButtonModule;
 	@Autowired
 	private BigBlueButtonManager bigBlueButtonManager;
 
@@ -77,9 +80,10 @@ public class BigBlueButtonAdminMeetingsController extends FormBasicController {
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
 		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.name));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.permanent));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(bigBlueButtonModule.isPermanentMeetingEnabled(), BMeetingsCols.permanent));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.start));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.end));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.template));
 		FlexiCellRenderer renderer = new StaticFlexiCellRenderer("resource", new TextFlexiCellRenderer());
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.resource.i18nHeaderKey(), BMeetingsCols.resource.ordinal(), "resource",
 				true, BMeetingsCols.resource.name(), renderer));
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminTemplatesController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminTemplatesController.java
index 5f1b083e3bc99bb87d60f6ccdc5a84847958697c..58a22151c9e10cf200d1f75b04efaaba6a290758 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminTemplatesController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonAdminTemplatesController.java
@@ -62,11 +62,14 @@ public class BigBlueButtonAdminTemplatesController extends FormBasicController {
 	private DialogBoxController confirmDelete;
 	private EditBigBlueButtonTemplateController editTemplateCtlr;
 	
+	private final boolean readOnly;
+	
 	@Autowired
 	private BigBlueButtonManager bigBlueButtonManager;
 	
-	public BigBlueButtonAdminTemplatesController(UserRequest ureq, WindowControl wControl) {
+	public BigBlueButtonAdminTemplatesController(UserRequest ureq, WindowControl wControl, boolean readOnly) {
 		super(ureq, wControl, "templates_admin");
+		this.readOnly = readOnly;
 		initForm(ureq);
 		updateModel();
 	}
@@ -74,14 +77,22 @@ public class BigBlueButtonAdminTemplatesController extends FormBasicController {
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
 		addTemplateButton = uifactory.addFormLink("add.template", formLayout, Link.BUTTON);
+		addTemplateButton.setVisible(!readOnly);
 		
 		//add the table
 		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BTemplatesCols.name));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BTemplatesCols.system));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("edit", translate("edit"), "edit"));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("delete", BTemplatesCols.system.ordinal(), "delete",
-				new BooleanCellRenderer(null, new StaticFlexiCellRenderer(translate("delete"), "delete"))));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BTemplatesCols.maxConcurrentMeetings));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BTemplatesCols.maxParticipants));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BTemplatesCols.webcamsOnlyForModerator));
+		if(readOnly) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("view", translate("view"), "view"));
+		} else {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("edit", translate("edit"), "edit"));
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("delete", BTemplatesCols.system.ordinal(), "delete",
+					new BooleanCellRenderer(null, new StaticFlexiCellRenderer(translate("delete"), "delete"))));
+		}
 		
 		tableModel = new BigBlueButtonTemplateTableModel(columnsModel, getLocale());
 		tableEl = uifactory.addTableElement(getWindowControl(), "templates", tableModel, getTranslator(), formLayout);
@@ -141,7 +152,7 @@ public class BigBlueButtonAdminTemplatesController extends FormBasicController {
 		} else if(tableEl == source) {
 			if(event instanceof SelectionEvent) {
 				SelectionEvent se = (SelectionEvent)event;
-				if("edit".equals(se.getCommand())) {
+				if("edit".equals(se.getCommand()) || "view".equals(se.getCommand())) {
 					doEditTemplate(ureq, tableModel.getObject(se.getIndex()));
 				} else if("delete".equals(se.getCommand())) {
 					doConfirmDelete(ureq, tableModel.getObject(se.getIndex()));
@@ -167,11 +178,16 @@ public class BigBlueButtonAdminTemplatesController extends FormBasicController {
 	private void doEditTemplate(UserRequest ureq, BigBlueButtonMeetingTemplate template) {
 		if(guardModalController(editTemplateCtlr)) return;
 		
-		editTemplateCtlr = new EditBigBlueButtonTemplateController(ureq, getWindowControl(), template);
+		editTemplateCtlr = new EditBigBlueButtonTemplateController(ureq, getWindowControl(), template, readOnly);
 		listenTo(editTemplateCtlr);
 		
-		cmc = new CloseableModalController(getWindowControl(), "close", editTemplateCtlr.getInitialComponent(),
-				true, translate("edit.template", new String[] { template.getName() }));
+		String title;
+		if(readOnly) {
+			title = translate("view.template", new String[] { template.getName() });
+		} else {
+			title = translate("edit.template", new String[] { template.getName() });
+		}
+		cmc = new CloseableModalController(getWindowControl(), "close", editTemplateCtlr.getInitialComponent(), true, title);
 		cmc.activate();
 		listenTo(cmc);
 	}
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonConfigurationController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonConfigurationController.java
index 122d4c104e8ce8223b2906e11c2af930944650b4..c3fde6fb9a72e9defe654806eb5792bde57ef6a4 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonConfigurationController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonConfigurationController.java
@@ -64,6 +64,8 @@ public class BigBlueButtonConfigurationController extends FormBasicController {
 	private SingleSelection cleanMeetingsEl;
 	private MultipleSelectionElement moduleEnabled;
 	private MultipleSelectionElement enabledForEl;
+	private MultipleSelectionElement permanentForEl;
+	private MultipleSelectionElement adhocForEl;
 
 	private static final String[] enabledKeys = new String[]{"on"};
 	private final String[] enabledValues;
@@ -98,7 +100,13 @@ public class BigBlueButtonConfigurationController extends FormBasicController {
 		enabledForEl = uifactory.addCheckboxesVertical("bigbluebutton.module.enabled.for", formLayout, FOR_KEYS, forValues, 1);
 		enabledForEl.select(FOR_KEYS[0], bigBlueButtonModule.isCoursesEnabled());
 		enabledForEl.select(FOR_KEYS[1], bigBlueButtonModule.isGroupsEnabled());
-			
+		
+		permanentForEl = uifactory.addCheckboxesHorizontal("enable.permanent.meeting", formLayout, enabledKeys, enabledValues);
+		permanentForEl.select(enabledKeys[0], bigBlueButtonModule.isPermanentMeetingEnabled());
+		
+		adhocForEl = uifactory.addCheckboxesHorizontal("enable.adhoc.meeting", formLayout, enabledKeys, enabledValues);
+		adhocForEl.select(enabledKeys[0], bigBlueButtonModule.isAdhocMeetingEnabled());
+
 		//spacer
 		spacerEl = uifactory.addSpacerElement("spacer", formLayout, false);
 
@@ -237,6 +245,9 @@ public class BigBlueButtonConfigurationController extends FormBasicController {
 				bigBlueButtonModule.setBigBlueButtonURI(new URI(url));
 				bigBlueButtonModule.setCoursesEnabled(enabledForEl.isSelected(0));
 				bigBlueButtonModule.setGroupsEnabled(enabledForEl.isSelected(1));
+				bigBlueButtonModule.setPermanentMeetingEnabled(permanentForEl.isAtLeastSelected(1));
+				bigBlueButtonModule.setAdhocMeetingEnabled(adhocForEl.isAtLeastSelected(1));
+
 				if(cleanMeetingsEl.isSelected(0)) {
 					bigBlueButtonModule.setCleanupMeetings(false);
 					bigBlueButtonModule.setDaysToKeep(null);
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java
index f75a5486f1a92089a3a47716397254ea3293bc88..ffaf19c6c2f485516fe99512f93ee072c1f8066f 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonEditMeetingsController.java
@@ -44,6 +44,7 @@ import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.bigbluebutton.BigBlueButtonManager;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.BigBlueButtonModule;
 import org.olat.modules.bigbluebutton.model.BigBlueButtonErrors;
 import org.olat.modules.bigbluebutton.ui.BigBlueButtonMeetingTableModel.BMeetingsCols;
 import org.olat.modules.gotomeeting.ui.GoToMeetingTableModel.MeetingsCols;
@@ -70,7 +71,9 @@ public class BigBlueButtonEditMeetingsController extends FormBasicController {
 	private final String subIdent;
 	private final RepositoryEntry entry;
 	private final BusinessGroup businessGroup;
-	
+
+	@Autowired
+	private BigBlueButtonModule bigBlueButtonModule;
 	@Autowired
 	private BigBlueButtonManager bigBlueButtonManager;
 	
@@ -94,9 +97,12 @@ public class BigBlueButtonEditMeetingsController extends FormBasicController {
 		//add the table
 		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.name));
-		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.permanent));
+		if(bigBlueButtonModule.isPermanentMeetingEnabled()) {
+			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.permanent));
+		}
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.start));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.end));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BMeetingsCols.template));
 		if(!readOnly) {
 			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("edit", translate("edit"), "edit"));
 			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("delete", translate("delete"), "delete"));
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java
index 4ed37f2d1056e5afb08689df2bc02fcee1ffc8ee..90e7dd179273d3822d571787fd09a04766756921 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingController.java
@@ -41,6 +41,7 @@ import org.olat.core.util.event.GenericEventListener;
 import org.olat.core.util.resource.OresHelper;
 import org.olat.modules.bigbluebutton.BigBlueButtonManager;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.BigBlueButtonModule;
 import org.olat.modules.bigbluebutton.model.BigBlueButtonErrors;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -57,12 +58,13 @@ public class BigBlueButtonMeetingController extends FormBasicController implemen
 	private final boolean administrator;
 	private BigBlueButtonMeeting meeting;
 	
-	private final boolean userMeetingsDates;
 	private final boolean moderatorStartMeeting;
 	private final OLATResourceable meetingOres;
 
 	private Link joinButton;
 
+	@Autowired
+	private BigBlueButtonModule bigBlueButtonModule;
 	@Autowired
 	private BigBlueButtonManager bigBlueButtonManager;
 	
@@ -76,12 +78,9 @@ public class BigBlueButtonMeetingController extends FormBasicController implemen
 		this.administrator = administrator;
 		meetingOres = OresHelper.createOLATResourceableInstance(BigBlueButtonMeeting.class.getSimpleName(), meeting.getKey());
 		CoordinatorManager.getInstance().getCoordinator().getEventBus().registerFor(this, getIdentity(), meetingOres);
-
-		userMeetingsDates = !meeting.isPermanent();
 		moderatorStartMeeting = configuration.isModeratorStartMeeting();
 		
 		initForm(ureq);
-
 		updateButtonsAndStatus();
 	}
 	
@@ -106,21 +105,21 @@ public class BigBlueButtonMeetingController extends FormBasicController implemen
 		
 		joinButton = LinkFactory.createButtonLarge("meeting.join.button", flc.getFormItemComponent(), this);
 		joinButton.setTarget("_blank");
-		joinButton.setVisible(!ended || moderator || administrator);
+		joinButton.setVisible(!ended);
 	}
 	
 	private boolean isEnded() {
 		return meeting != null && meeting.getEndDate() != null && new Date().after(meeting.getEndDate());
 	}
 	
-	private boolean isValidDates() {
-		if(!userMeetingsDates) {
-			return true;
+	private boolean isAccessible() {
+		if(meeting.isPermanent()) {
+			return bigBlueButtonModule.isPermanentMeetingEnabled();
 		}
+
 		Date now = new Date();
 		Date start = meeting.getStartWithLeadTime();
 		Date end = meeting.getEndWithFollowupTime();
-		
 		return !((start != null && start.compareTo(now) >= 0) || (end != null && end.compareTo(now) <= 0));
 	}
 	
@@ -130,42 +129,31 @@ public class BigBlueButtonMeetingController extends FormBasicController implemen
 	}
 	
 	private void updateButtonsAndStatus() {
-		boolean meetingsExists = StringHelper.containsNonWhitespace(meeting.getMeetingId());
 		boolean isEnded = isEnded();
-
-		flc.contextPut("meetingsExists", Boolean.valueOf(meetingsExists));
+		boolean accessible = isAccessible();
 		flc.contextPut("ended", Boolean.valueOf(isEnded));
-		
-		boolean accessible = !isEnded() || administrator || moderator;
-		boolean running = bigBlueButtonManager.isMeetingRunning(meeting);
-		if(moderator || administrator) {
-			joinButton.setVisible(accessible);
-			joinButton.setEnabled(!readOnly);
+		flc.contextPut("notStarted", Boolean.TRUE);
+		joinButton.setVisible(accessible);
+		joinButton.setEnabled(!readOnly);
 			
-			if(!running && moderatorStartMeeting) {
-				joinButton.setCustomDisplayText(translate("meeting.start.button"));
-			} else if(isValidDates()) {
-				joinButton.setCustomDisplayText(translate("meeting.join.button"));
-			} else {
-				joinButton.setCustomDisplayText(translate("meeting.go.button"));
-			}
-		} else {
-			boolean validDates = isValidDates();
-
-			joinButton.setVisible(accessible);
-			if(!running && moderatorStartMeeting) {
+		if(accessible) {
+			boolean running = bigBlueButtonManager.isMeetingRunning(meeting);
+			if(moderator || administrator) {
+				flc.contextPut("notStarted", Boolean.FALSE);
+				if(!running && moderatorStartMeeting) {
+					joinButton.setCustomDisplayText(translate("meeting.start.button"));
+				} else {
+					joinButton.setCustomDisplayText(translate("meeting.join.button"));
+				}
+			} else if(!running && moderatorStartMeeting) {
+				flc.contextPut("notStarted", Boolean.TRUE);
 				joinButton.setEnabled(false);
 			} else {
-				joinButton.setEnabled(!readOnly && validDates);
-			}
-
-			if(validDates && !running && moderatorStartMeeting) {
-				flc.contextPut("notStarted", Boolean.TRUE);	
-			} else if(validDates || isEnded) {
 				flc.contextPut("notStarted", Boolean.FALSE);
-			} else {
-				flc.contextPut("notStarted", Boolean.TRUE);
+				joinButton.setEnabled(!readOnly);
 			}
+		} else if(isEnded) {
+			flc.contextPut("notStarted", Boolean.FALSE);
 		}
 	}
 
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingTableModel.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingTableModel.java
index 983104ad20ebf991a6cd534671be3cabb67e8f0d..cb1f53b817478383e645a3483ac6b1b4ec936ec8 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingTableModel.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingTableModel.java
@@ -29,6 +29,7 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTable
 import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.BigBlueButtonMeetingTemplate;
 
 /**
  * 
@@ -69,11 +70,17 @@ implements SortableFlexiTableDataModel<BigBlueButtonMeeting> {
 			case permanent: return Boolean.valueOf(row.isPermanent());
 			case start: return row.getStartDate();
 			case end: return row.getEndDate();
+			case template: return getTemplate(row);
 			case resource: return getResourceName(row);
 			default: return "ERROR";
 		}
 	}
 	
+	private String getTemplate(BigBlueButtonMeeting row) {
+		BigBlueButtonMeetingTemplate template = row.getTemplate();
+		return template == null ? null: template.getName();
+	}
+	
 	private String getResourceName(BigBlueButtonMeeting row) {
 		String displayName = null;
 		if(row.getEntry() != null) {
@@ -95,6 +102,7 @@ implements SortableFlexiTableDataModel<BigBlueButtonMeeting> {
 		permanent("table.header.permanent"),
 		start("meeting.start"),
 		end("meeting.end"),
+		template("table.header.template"),
 		resource("meeting.resource");
 		
 		private final String i18nHeaderKey;
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingsController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingsController.java
index 3dec4134a52eb21dfb16aead0da21ddb81fca8ae..0d9daf74c94fb3516e61b64d435c0f2fbf916df1 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingsController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonMeetingsController.java
@@ -41,6 +41,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.group.BusinessGroup;
 import org.olat.modules.bigbluebutton.BigBlueButtonManager;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.BigBlueButtonModule;
 import org.olat.modules.bigbluebutton.ui.BigBlueButtonMeetingTableModel.BMeetingsCols;
 import org.olat.repository.RepositoryEntry;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -62,7 +63,9 @@ public class BigBlueButtonMeetingsController extends FormBasicController {
 	private final String subIdent;
 	private final BusinessGroup businessGroup;
 	private final boolean showPermanentCol;
-	
+
+	@Autowired
+	private BigBlueButtonModule bigBlueButtonModule;
 	@Autowired
 	private BigBlueButtonManager bigBlueButtonManager;
 	
@@ -72,7 +75,7 @@ public class BigBlueButtonMeetingsController extends FormBasicController {
 		this.entry = entry;
 		this.subIdent = subIdent;
 		this.businessGroup = businessGroup;
-		showPermanentCol = (administrator || moderator);
+		showPermanentCol = (administrator || moderator) && bigBlueButtonModule.isPermanentMeetingEnabled();
 		
 		initForm(ureq);
 		updateModel();
@@ -95,7 +98,7 @@ public class BigBlueButtonMeetingsController extends FormBasicController {
 		upcomingTableEl.setEmtpyTableMessageKey("no.upcoming.meetings");
 		
 		FlexiTableSortOptions sortOptions = new FlexiTableSortOptions();
-		sortOptions.setDefaultOrderBy(new SortKey(BMeetingsCols.start.name(), false));
+		sortOptions.setDefaultOrderBy(new SortKey(BMeetingsCols.start.name(), true));
 		upcomingTableEl.setSortSettings(sortOptions);
 		upcomingTableEl.setAndLoadPersistedPreferences(ureq, "big-blue-button-upcoming-meetings-list");
 
@@ -113,7 +116,7 @@ public class BigBlueButtonMeetingsController extends FormBasicController {
 		pastTableEl = uifactory.addTableElement(getWindowControl(), "pastMeetings", pastTableModel, getTranslator(), formLayout);
 		
 		FlexiTableSortOptions pastSortOptions = new FlexiTableSortOptions();
-		pastSortOptions.setDefaultOrderBy(new SortKey(BMeetingsCols.start.name(), false));
+		pastSortOptions.setDefaultOrderBy(new SortKey(BMeetingsCols.start.name(), true));
 		pastTableEl.setSortSettings(pastSortOptions);
 		pastTableEl.setAndLoadPersistedPreferences(ureq, "big-blue-button-past-meetings-list");
 	}
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonTemplateTableModel.java b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonTemplateTableModel.java
index dd1cdc551d7d54f2dc8847e628affa087574dfa9..65f46b2dadca5d7561ec797769c71ee019e4585d 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonTemplateTableModel.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/BigBlueButtonTemplateTableModel.java
@@ -67,6 +67,9 @@ implements SortableFlexiTableDataModel<BigBlueButtonMeetingTemplate> {
 		switch(COLS[col]) {
 			case name: return row.getName();
 			case system: return Boolean.valueOf(row.isSystem());
+			case maxConcurrentMeetings: return row.getMaxConcurrentMeetings();
+			case maxParticipants: return row.getMaxParticipants();
+			case webcamsOnlyForModerator: return row.getWebcamsOnlyForModerator();
 			default: return "ERROR";
 		}
 	}
@@ -79,7 +82,10 @@ implements SortableFlexiTableDataModel<BigBlueButtonMeetingTemplate> {
 	public enum BTemplatesCols implements FlexiSortableColumnDef {
 		
 		name("meeting.name"),
-		system("table.header.system");
+		system("table.header.system"),
+		maxConcurrentMeetings("table.header.max.concurrent.meetings"),
+		maxParticipants("table.header.max.participants"),
+		webcamsOnlyForModerator("table.header.webcams.only.moderator");
 		
 		private final String i18nHeaderKey;
 		
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java
index 3396fa973eca838dc1de642d6b4108a7493e2278..6d0bbd2a58667e47edf8c4ed19144d8b754e3fb3 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonMeetingController.java
@@ -41,6 +41,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.modules.bigbluebutton.BigBlueButtonManager;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeetingTemplate;
+import org.olat.modules.bigbluebutton.BigBlueButtonModule;
 import org.olat.repository.RepositoryEntry;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -70,6 +71,8 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 	private BigBlueButtonMeeting meeting;
 	private List<BigBlueButtonMeetingTemplate> templates;
 	
+	@Autowired
+	private BigBlueButtonModule bigBlueButtonModule;
 	@Autowired
 	private BigBlueButtonManager bigBlueButtonManager;
 	
@@ -113,13 +116,13 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 		welcomeEl = uifactory.addRichTextElementForStringDataMinimalistic("meeting.welcome", "meeting.welcome", welcome, 8, 60, formLayout, getWindowControl());
 		
 		KeyValues templatesKeyValues = new KeyValues();
-		templatesKeyValues.add(KeyValues.entry("-", translate("meeting.no.template")));
 		for(BigBlueButtonMeetingTemplate template:templates) {
 			templatesKeyValues.add(KeyValues.entry(template.getKey().toString(), template.getName()));
 		}
 		String[] templatesKeys = templatesKeyValues.keys();
 		templateEl = uifactory.addDropdownSingleselect("meeting.template", "meeting.template", formLayout,
 				templatesKeys, templatesKeyValues.values());
+		templateEl.addActionListener(FormEvent.ONCHANGE);
 		templateEl.setMandatory(true);
 		boolean templateSelected = false;
 		if(meeting != null && meeting.getTemplate() != null) {
@@ -134,13 +137,15 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 		if(!templateSelected) {
 			templateEl.select(templatesKeys[0], true);
 		}
+		updateTemplateInformations();
 		
 		String[] permValues = new String[] { translate("meeting.permanent.on") };
 		permanentEl = uifactory.addCheckboxesHorizontal("meeting.permanent", formLayout, permKeys, permValues);
 		permanentEl.addActionListener(FormEvent.ONCHANGE);
-		boolean permanent = meeting == null ? false : meeting.isPermanent();
+		boolean permanent = meeting != null && bigBlueButtonModule.isPermanentMeetingEnabled() && meeting.isPermanent();
 		permanentEl.select(permKeys[0], permanent);
 		permanentEl.setHelpTextKey("meeting.permanent.explain", null);
+		permanentEl.setVisible(bigBlueButtonModule.isPermanentMeetingEnabled());
 
 		Date startDate = meeting == null ? null : meeting.getStartDate();
 		startDateEl = uifactory.addDateChooser("meeting.start", "meeting.start", startDate, formLayout);
@@ -173,6 +178,21 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 		followupTimeEl.setVisible(!permanent);
 	}
 	
+	private void updateTemplateInformations() {
+		templateEl.setExampleKey(null, null);
+		if(templateEl.isOneSelected()) {
+			BigBlueButtonMeetingTemplate template = getSelectedTemplate();
+			if(template != null && template.getMaxParticipants() != null) {
+				String[] args = new String[] { template.getMaxParticipants().toString() };
+				if(template.getWebcamsOnlyForModerator() != null && template.getWebcamsOnlyForModerator().booleanValue()) {
+					templateEl.setExampleKey("template.explain.max.participants.with.webcams.mod", args);
+				} else {
+					templateEl.setExampleKey("template.explain.max.participants", args);
+				}
+			}
+		}
+	}
+	
 	@Override
 	protected void doDispose() {
 		//
@@ -181,19 +201,10 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
 		boolean allOk = super.validateFormLogic(ureq);
-		
-		nameEl.clearError();
-		if(!StringHelper.containsNonWhitespace(nameEl.getValue())) {
-			nameEl.setErrorKey("form.legende.mandatory", null);
-			allOk &= false;
-		} else if (nameEl.getValue().contains("&")) {
-			nameEl.setErrorKey("form.invalidchar.noamp", null);
-			allOk &= false;
-		}
-		
+
 		startDateEl.clearError();
 		endDateEl.clearError();
-		if(!permanentEl.isAtLeastSelected(1)) {
+		if(!permanentEl.isVisible() || !permanentEl.isAtLeastSelected(1)) {
 			if(startDateEl.getDate() == null) {
 				startDateEl.setErrorKey("form.legende.mandatory", null);
 				allOk &= false;
@@ -210,11 +221,41 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 					endDateEl.setErrorKey("error.start.after.end", null);
 					allOk &= false;
 				}
+				
+				Date now = new Date();
+				if(end.before(now)) {
+					endDateEl.setErrorKey("error.end.past", null);
+					allOk &= false;
+				}
 			}
 		}
 		
 		allOk &= validateTime(leadTimeEl);
 		allOk &= validateTime(followupTimeEl);
+		
+		templateEl.clearError();
+		if(!templateEl.isOneSelected()) {
+			endDateEl.setErrorKey("form.legende.mandatory", null);
+			allOk &= false;
+		}
+		
+		// dates ok
+		if(allOk && (!permanentEl.isVisible() || !permanentEl.isAtLeastSelected(1))) {
+			boolean canMeeting = validateSlot();
+			if(!canMeeting) {
+				startDateEl.setErrorKey("server.overloaded", null);
+				allOk &= false;
+			}
+		}
+		
+		nameEl.clearError();
+		if(!StringHelper.containsNonWhitespace(nameEl.getValue())) {
+			nameEl.setErrorKey("form.legende.mandatory", null);
+			allOk &= false;
+		} else if (nameEl.getValue().contains("&")) {
+			nameEl.setErrorKey("form.invalidchar.noamp", null);
+			allOk &= false;
+		}
 		return allOk;
 	}
 	
@@ -227,11 +268,43 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 		}
 		return allOk;
 	}
+	
+	private boolean validateSlot() {
+		BigBlueButtonMeetingTemplate template = getSelectedTemplate();
+		return bigBlueButtonManager.isSlotAvailable(template,
+				startDateEl.getDate(), getLeadTime(), endDateEl.getDate(), getFollowupTime());
+	}
+	
+	private BigBlueButtonMeetingTemplate getSelectedTemplate() {
+		String selectedTemplateId = templateEl.getSelectedKey();
+		return templates.stream()
+					.filter(tpl -> selectedTemplateId.equals(tpl.getKey().toString()))
+					.findFirst()
+					.orElse(null);
+	}
+	
+	public long getLeadTime() {
+		long leadTime = 0;
+		if(leadTimeEl.isVisible() && StringHelper.isLong(leadTimeEl.getValue())) {
+			leadTime = Long.valueOf(leadTimeEl.getValue());
+		}
+		return leadTime;
+	}
+	
+	private long getFollowupTime() {
+		long followupTime = 0;
+		if(followupTimeEl.isVisible() && StringHelper.isLong(followupTimeEl.getValue())) {
+			followupTime = Long.valueOf(followupTimeEl.getValue());
+		}
+		return followupTime;
+	}
 
 	@Override
 	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
 		if(permanentEl == source) {
 			updateUI();
+		} else if(templateEl == source) {
+			updateTemplateInformations();
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
@@ -247,22 +320,10 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 		
 		meeting.setDescription(descriptionEl.getValue());
 		meeting.setWelcome(welcomeEl.getValue());
-		BigBlueButtonMeetingTemplate template = null;
-		if(templateEl.isOneSelected() && !"-".equals(templateEl.getSelectedKey())) {
-			String selectedTemplateId = templateEl.getSelectedKey();
-			template = templates.stream()
-					.filter(tpl -> selectedTemplateId.equals(tpl.getKey().toString()))
-					.findFirst()
-					.orElse(null);
-		}
+		BigBlueButtonMeetingTemplate template = getSelectedTemplate();
 		meeting.setTemplate(template);
 		
-		boolean permanent;	
-		if(permanentEl.isVisible()) {
-			permanent = permanentEl.isAtLeastSelected(1);
-		} else {
-			permanent = false;
-		}
+		boolean permanent = permanentEl.isVisible() && permanentEl.isAtLeastSelected(1);
 		meeting.setPermanent(permanent);
 		if(permanent) {
 			meeting.setStartDate(null);
@@ -271,20 +332,12 @@ public class EditBigBlueButtonMeetingController extends FormBasicController {
 			meeting.setFollowupTime(0l);
 		} else {
 			Date startDate = startDateEl.getDate();
-			Date endDate = endDateEl.getDate();
 			meeting.setStartDate(startDate);
+			Date endDate = endDateEl.getDate();
 			meeting.setEndDate(endDate);
-			
-			long leadTime = 0;
-			if(leadTimeEl.isVisible() && StringHelper.isLong(leadTimeEl.getValue())) {
-				leadTime = Long.valueOf(leadTimeEl.getValue());
-			}
+			long leadTime = getLeadTime();
 			meeting.setLeadTime(leadTime);
-			
-			long followupTime = 0;
-			if(followupTimeEl.isVisible() && StringHelper.isLong(followupTimeEl.getValue())) {
-				followupTime = Long.valueOf(followupTimeEl.getValue());
-			}
+			long followupTime = getFollowupTime();
 			meeting.setFollowupTime(followupTime);
 		}
 		
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonTemplateController.java b/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonTemplateController.java
index 224e4c90afc3db0f6823dd5f4ffca6ed2969e837..ad3e171277dec60577cc677ba505fda051db3f36 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonTemplateController.java
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/EditBigBlueButtonTemplateController.java
@@ -44,13 +44,14 @@ import org.springframework.beans.factory.annotation.Autowired;
 public class EditBigBlueButtonTemplateController extends FormBasicController {
 
 	private static final String[] maxParticipantsKeys = new String[] { "2", "5", "10", "25", "50", "100" };
-	private static final String[] onKeys = new String[] { "yes", "no", "default" };
+	private static final String[] onKeys = new String[] { "yes", "no" };
 	private static final String[] guestPolicyKeys = new String[] {
 			GuestPolicyEnum.ALWAYS_DENY.name(), GuestPolicyEnum.ASK_MODERATOR.name(), GuestPolicyEnum.ALWAYS_ACCEPT.name()
 		};
 	
 	private TextElement nameEl;
 	private TextElement descriptionEl;
+	private TextElement maxConcurrentMeetingsEl;
 	private SingleSelection muteOnStartEl;
 	private SingleSelection maxParticipantsEl;
 	private SingleSelection autoStartRecordingEl;
@@ -66,6 +67,7 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 
 	private SingleSelection guestPolicyEl;
 	
+	private final boolean readOnly;
 	private BigBlueButtonMeetingTemplate template;
 	
 	@Autowired
@@ -73,13 +75,15 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 	
 	public EditBigBlueButtonTemplateController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl);
+		readOnly = false;
 		initForm(ureq);
 	}
 	
-	public EditBigBlueButtonTemplateController(UserRequest ureq, WindowControl wControl, BigBlueButtonMeetingTemplate template) {
+	public EditBigBlueButtonTemplateController(UserRequest ureq, WindowControl wControl,
+			BigBlueButtonMeetingTemplate template, boolean readOnly) {
 		super(ureq, wControl);
+		this.readOnly = readOnly;
 		this.template = template;
-
 		initForm(ureq);
 	}
 
@@ -95,9 +99,11 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 		String description = template == null ? "" : template.getDescription();
 		descriptionEl = uifactory.addTextAreaElement("template.description", "template.description", 2000, 4, 72, false, false, description, formLayout);
 		
-		String maxParticipants = template == null || template.getMaxParticipants() == null ? "-" : template.getMaxParticipants().toString();
+		String maxConcurrentMeetings = template == null || template.getMaxConcurrentMeetings() == null ? "" : template.getMaxConcurrentMeetings().toString();
+		maxConcurrentMeetingsEl = uifactory.addTextElement("template.max.concurrent.meetings", "template.max.concurrent.meetings", 8, maxConcurrentMeetings, formLayout);
+		
+		String maxParticipants = template == null || template.getMaxParticipants() == null ? "5" : template.getMaxParticipants().toString();
 		KeyValues maxParticipantsKeyValues = new KeyValues();
-		maxParticipantsKeyValues.add(KeyValues.entry("-", translate("template.maxParticipants.default")));
 		for(String maxParticipantsKey:maxParticipantsKeys) {
 			maxParticipantsKeyValues.add(KeyValues.entry(maxParticipantsKey, maxParticipantsKey));
 		}
@@ -108,51 +114,51 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 				maxParticipantsKeyValues.keys(), maxParticipantsKeyValues.values());
 		maxParticipantsEl.select(maxParticipants, true);
 		
-		String[] onValues = new String[] { "Yes", "No", "Default" };
+		String[] onValues = new String[] { translate("yes"), translate("no")  };
 		
 		Boolean muteOnStart = template == null ? null : template.getMuteOnStart();
 		muteOnStartEl = uifactory.addRadiosHorizontal("template.muteOnStart", formLayout, onKeys, onValues);
-		select(muteOnStart, muteOnStartEl);
+		select(muteOnStart, muteOnStartEl, false);
 		
 		Boolean autoStartRecording = template == null ? null : template.getAutoStartRecording();
 		autoStartRecordingEl = uifactory.addRadiosHorizontal("template.autoStartRecording", formLayout, onKeys, onValues);
-		select(autoStartRecording, autoStartRecordingEl);
+		select(autoStartRecording, autoStartRecordingEl, false);
 		
 		Boolean allowStartStopRecording = template == null ? null : template.getAllowStartStopRecording();
 		allowStartStopRecordingEl = uifactory.addRadiosHorizontal("template.allowStartStopRecording", formLayout, onKeys, onValues);
-		select(allowStartStopRecording, allowStartStopRecordingEl);
+		select(allowStartStopRecording, allowStartStopRecordingEl, true);
 		
 		Boolean webcamsOnlyForModerator = template == null ? null : template.getWebcamsOnlyForModerator();
 		webcamsOnlyForModeratorEl = uifactory.addRadiosHorizontal("template.webcamsOnlyForModerator", formLayout, onKeys, onValues);
-		select(webcamsOnlyForModerator, webcamsOnlyForModeratorEl);
+		select(webcamsOnlyForModerator, webcamsOnlyForModeratorEl, true);
 		
 		Boolean allowModsToUnmuteUsers = template == null ? null : template.getAllowModsToUnmuteUsers();
 		allowModsToUnmuteUsersEl = uifactory.addRadiosHorizontal("template.allowModsToUnmuteUsers", formLayout, onKeys, onValues);
-		select(allowModsToUnmuteUsers, allowModsToUnmuteUsersEl);
+		select(allowModsToUnmuteUsers, allowModsToUnmuteUsersEl, false);
 		
 		Boolean lockSettingsDisableCam = template == null ? null : template.getLockSettingsDisableCam();
 		lockSettingsDisableCamEl = uifactory.addRadiosHorizontal("template.lockSettingsDisableCam", formLayout, onKeys, onValues);
-		select(lockSettingsDisableCam, lockSettingsDisableCamEl);
+		select(lockSettingsDisableCam, lockSettingsDisableCamEl, false);
 		
 		Boolean lockSettingsDisableMic = template == null ? null : template.getLockSettingsDisableMic();
 		lockSettingsDisableMicEl = uifactory.addRadiosHorizontal("template.lockSettingsDisableMic", formLayout, onKeys, onValues);
-		select(lockSettingsDisableMic, lockSettingsDisableMicEl);
+		select(lockSettingsDisableMic, lockSettingsDisableMicEl, false);
 		
 		Boolean lockSettingsDisablePrivateChat = template == null ? null : template.getLockSettingsDisablePrivateChat();
 		lockSettingsDisablePrivateChatEl =  uifactory.addRadiosHorizontal("template.lockSettingsDisablePrivateChat", formLayout, onKeys, onValues);
-		select(lockSettingsDisablePrivateChat, lockSettingsDisablePrivateChatEl);
+		select(lockSettingsDisablePrivateChat, lockSettingsDisablePrivateChatEl, false);
 		
 		Boolean lockSettingsDisablePublicChat = template == null ? null : template.getLockSettingsDisablePublicChat();
 		lockSettingsDisablePublicChatEl =  uifactory.addRadiosHorizontal("template.lockSettingsDisablePublicChat", formLayout, onKeys, onValues);
-		select(lockSettingsDisablePublicChat, lockSettingsDisablePublicChatEl);
+		select(lockSettingsDisablePublicChat, lockSettingsDisablePublicChatEl, false);
 		
 		Boolean lockSettingsDisableNote = template == null ? null : template.getLockSettingsDisableNote();
 		lockSettingsDisableNoteEl =  uifactory.addRadiosHorizontal("template.lockSettingsDisableNote", formLayout, onKeys, onValues);
-		select(lockSettingsDisableNote, lockSettingsDisableNoteEl);
+		select(lockSettingsDisableNote, lockSettingsDisableNoteEl, false);
 		
 		Boolean lockSettingsLockedLayout = template == null ? null : template.getLockSettingsLockedLayout();
 		lockSettingsLockedLayoutEl = uifactory.addRadiosHorizontal("template.lockSettingsLockedLayout", formLayout, onKeys, onValues);
-		select(lockSettingsLockedLayout, lockSettingsLockedLayoutEl);
+		select(lockSettingsLockedLayout, lockSettingsLockedLayoutEl, false);
 
 		GuestPolicyEnum guestPolicy = template == null ? GuestPolicyEnum.ALWAYS_DENY : template.getGuestPolicyEnum();
 		String[] guestPolicyValues = new String[] {
@@ -166,10 +172,10 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 		formLayout.add("buttons", buttonLayout);
 		uifactory.addFormCancelButton("cancel", buttonLayout, ureq, getWindowControl());
 		
-		if(template == null ||  !template.isSystem()) {
-			uifactory.addFormSubmitButton("save", buttonLayout);
-		} else {
+		if(readOnly) {
 			disableSystemTemplate();
+		} else {
+			uifactory.addFormSubmitButton("save", buttonLayout);
 		}
 	}
 	
@@ -177,6 +183,7 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 		nameEl.setEnabled(false);
 		descriptionEl.setEnabled(false);
 		muteOnStartEl.setEnabled(false);
+		maxConcurrentMeetingsEl.setEnabled(false);
 		maxParticipantsEl.setEnabled(false);
 		autoStartRecordingEl.setEnabled(false);
 		allowStartStopRecordingEl.setEnabled(false);
@@ -191,10 +198,11 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 		guestPolicyEl.setEnabled(false);
 	}
 	
-	private void select(Boolean val, SingleSelection selectEl) {
+	private void select(Boolean val, SingleSelection selectEl, boolean defaultValue) {
 		if(val == null) {
-			selectEl.select(onKeys[2], true);
-		} else if(val.booleanValue()) {
+			val = Boolean.valueOf(defaultValue);
+		}
+		if(val.booleanValue()) {
 			selectEl.select(onKeys[0], true);
 		} else {
 			selectEl.select(onKeys[1], true);
@@ -221,7 +229,15 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 		
 		descriptionEl.clearError();
 		if(!StringHelper.containsNonWhitespace(descriptionEl.getValue()) && descriptionEl.getValue().length() > 2000) {
-			nameEl.setErrorKey("form.error.toolong", new String[] { "2000" });
+			descriptionEl.setErrorKey("form.error.toolong", new String[] { "2000" });
+			allOk &= false;
+		}
+		
+		maxConcurrentMeetingsEl.clearError();
+		if(StringHelper.containsNonWhitespace(maxConcurrentMeetingsEl.getValue())
+				&& (!StringHelper.isLong(maxConcurrentMeetingsEl.getValue())
+						|| Long.valueOf(maxConcurrentMeetingsEl.getValue()).longValue() <= 0)) {
+			maxConcurrentMeetingsEl.setErrorKey("form.error.nointeger", null);
 			allOk &= false;
 		}
 		
@@ -237,6 +253,13 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 		}
 		template.setDescription(descriptionEl.getValue());
 		
+		if(StringHelper.containsNonWhitespace(maxConcurrentMeetingsEl.getValue())
+				&& StringHelper.isLong(maxConcurrentMeetingsEl.getValue())) {
+			template.setMaxConcurrentMeetings(Long.valueOf(maxConcurrentMeetingsEl.getValue()).intValue());
+		} else {
+			template.setMaxConcurrentMeetings(null);
+		}
+
 		if(maxParticipantsEl.isOneSelected() && !"-".equals(maxParticipantsEl.getSelectedKey())) {
 			template.setMaxParticipants(Integer.parseInt(maxParticipantsEl.getSelectedKey()));
 		} else {
@@ -263,14 +286,10 @@ public class EditBigBlueButtonTemplateController extends FormBasicController {
 	}
 	
 	private Boolean getSelected(SingleSelection selectEl) {
-		Boolean val = null;
+		Boolean val = Boolean.FALSE;
 		if(selectEl.isOneSelected()) {
 			String selected = selectEl.getSelectedKey();
-			if("yes".equals(selected)) {
-				val = Boolean.TRUE;
-			} else if("no".equals(selected)) {
-				val = Boolean.FALSE;
-			}
+			val = Boolean.valueOf("yes".equals(selected));
 		}
 		return val;
 	}
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html
index 897c719b205351815dc72e35df00bd8bb8aa91a9..b81c8189e336df7749c360f8d492f6158c4f09e5 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meeting.html
@@ -12,7 +12,7 @@
 	<div class="o_block_large o_warning">$r.translate("meeting.ended")</div>
 #end
 
-#if($r.isFalse($meetingsExists) || $r.isTrue($notStarted))
+#if($r.isTrue($notStarted))
 <div class="o_block_large o_info">$r.translate("meeting.create.intro")</div>
 #end
 
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings.html b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings.html
index ea913fe6bd88b3fce4ae6b62975a523c646eeb8c..6a9f6a139c175cd383ec23fb84afee5dbc0a54fe 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings.html
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/meetings.html
@@ -1,6 +1,8 @@
 <h3>$r.translate("meetings.upcoming")</h3>
 $r.render("upcomingMeetings")
 #if($r.visible("pastMeetings"))
+<div class="o_block_large">
 	<h3>$r.translate("meetings.past")</h3>
 	$r.render("pastMeetings")
+</div>
 #end
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html
index 49cfbf886d4e6062b664b94ce2da7b81a458f72a..0dcce15ec3197f5e3cb5185a210d0f29f6b34549 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_content/run_admin.html
@@ -3,7 +3,7 @@
 	$r.render("backLink")
 	$r.render("meeting")
 #else
-	$r.render("segments")<br>	
+	$r.render("segments")	
 	#if($r.available("segmentCmp"))
 		$r.render("segmentCmp")
 	#end
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties
index 9d53db5c503fdf85ad9359e93dee81fe4b509c6d..afd1385db88b43fc6d859074880a23b2629c6e1f 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_de.properties
@@ -4,7 +4,7 @@ add.meeting=Meeting hinzuf\u00FCgen
 add.template=Vorlage erstellen
 admin.menu.title=BigBlueButton
 admin.menu.title.alt=BigBlueButton
-bigbluebutton.intro=Intro
+bigbluebutton.intro=Konfiguration von BigBlueButton Web Conferencing
 bigbluebutton.module.enabled=Modul "BigBlueButton"
 bigbluebutton.module.enabled.for=Einschalten f\u00FCr
 bigbluebutton.module.enabled.for.courses=Kurse
@@ -18,6 +18,9 @@ confirm.delete.template.title=Vorlage "{0}" l\u00F6schen
 connection.failed=Login fehlgeschlagen.
 connection.successful=Login erfolgreich\!
 edit.template=Vorlage "{0}" bearbeiten
+enable.permanent.meeting=Dauernd Meeting einschalten
+enable.adhoc.meeting=Adhoc Meeting einschalten
+error.end.past=Meeting kann nicht in Vergangenheit geplant werden.
 error.prefix=Ein Fehler ist aufgetreten\:
 error.server.raw={1} <small>Schl\u00FCssel\: {0}</small>
 error.start.after.end=Das Datum f\u00FCr das Ende des Meetings darf nicht vor dem Beginn Datum sein.
@@ -55,12 +58,19 @@ option.bigbluebutton.secret=Secret
 option.bigbluebutton.shared.secret=Shared secret
 option.clean.meetings=Meetings aufra\u00FCmen (Tage)
 option.dont.clean.meetings=Nie
+server.overloaded=Es gibt kein Platz verf\u00FCgbar auf dem Server an den gew\u00E4hlten Datum.
 table.header.permanent=Dauernd
 table.header.system=System
+table.header.max.concurrent.meetings=Gleichseitig Meetings
+table.header.max.participants=Max. Teilnehmer
+table.header.template=Typ
+table.header.webcams.only.moderator=Webcams Moderatoren
 template.allowModsToUnmuteUsers=Allow moderators to unmute users
 template.allowStartStopRecording=Allow to start / stop recording
 template.autoStartRecording=Auto start recording
 template.description=Beschreibung
+template.explain.max.participants=Max. Anzhal von Teilnehmer: {0}
+template.explain.max.participants.with.webcams.mod=Max. Anzhal von Teilnehmer: {0}, Webcams f\u00FCr Moderatoren
 template.guestPolicy=Guest policy
 template.lockSettingsDisableCam=Lock settings disable camera
 template.lockSettingsDisableMic=Lock settings disable micro
@@ -70,8 +80,11 @@ template.lockSettingsDisablePublicChat=Lock settings disable public chat
 template.lockSettingsLockedLayout=Lock settings locked layout
 template.maxParticipants=Max. Teilnehmer
 template.maxParticipants.default=Standard
+template.max.concurrent.meetings=Max. gleichzeitige Meetings
 template.muteOnStart=Mute on start
 template.name=Name
 template.webcamsOnlyForModerator=Webcams only for moderators
 templates.title=Vorlagen
+view=Ansehen
+view.template=Vorlage "{0}"
 warning.template.in.use=Die Vorlage kann nicht gel\u00F6scht werden weil sie nocht benutzt wird.
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_en.properties
index 63767caff0e28189188ebfdbebe269edae61cf6a..5d4a4e88929626e6a096cb1ee4638ef6b20538eb 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_en.properties
@@ -4,7 +4,7 @@ add.meeting=Add meeting
 add.template=New template
 admin.menu.title=BigBlueButton
 admin.menu.title.alt=BigBlueButton
-bigbluebutton.intro=Intro
+bigbluebutton.intro=Configuration of BigBlueButton Web Conferencing
 bigbluebutton.module.enabled=Module "BigBlueButton"
 bigbluebutton.module.enabled.for=Enable for
 bigbluebutton.module.enabled.for.courses=Courses
@@ -18,6 +18,9 @@ confirm.delete.template.title=Delete template "{0}"
 connection.failed=Login failed.
 connection.successful=Login successful\!
 edit.template=Edit template "{0}"
+enable.permanent.meeting=Enable permanent meeting
+enable.adhoc.meeting=Enable adhoc meeting
+error.end.past=Meeting cannot be planned in the past.
 error.prefix=An error happened\:
 error.server.raw={1} <small>Key {0}</small>
 error.start.after.end=The end date of the meeting must not be before the start date.
@@ -55,12 +58,19 @@ option.bigbluebutton.secret=Secret
 option.bigbluebutton.shared.secret=Shared secret
 option.clean.meetings=Clean-up meetings (days)
 option.dont.clean.meetings=Never
+server.overloaded=There is no place available on the server for the choosen dates.
 table.header.permanent=Permanent
 table.header.system=System
+table.header.max.concurrent.meetings=Concurrent meetings
+table.header.max.participants=Max. participants
+table.header.template=Type
+table.header.webcams.only.moderator=Webcams moderators
 template.allowModsToUnmuteUsers=Allow moderators to unmute users
 template.allowStartStopRecording=Allow to start / stop recording
 template.autoStartRecording=Auto start recording
 template.description=Description
+template.explain.max.participants=Max. number of participants: {0}
+template.explain.max.participants.with.webcams.mod=Max. number of participants: {0}, webcams for moderators
 template.guestPolicy=Guest policy
 template.lockSettingsDisableCam=Lock settings disable camera
 template.lockSettingsDisableMic=Lock settings disable micro
@@ -70,9 +80,12 @@ template.lockSettingsDisablePublicChat=Lock settings disable public chat
 template.lockSettingsLockedLayout=Lock settings locked layout
 template.maxParticipants=Max. participants
 template.maxParticipants.default=Default
+template.max.concurrent.meetings=Max. concurrent meetings
 template.muteOnStart=Mute on start
 template.name=Name
 template.webcamsOnlyForModerator=Webcams only for moderators
 templates.title=Templates
+view=View
+view.template=Template "{0}"
 warning.template.in.use=The template cannot be deleted. It's still used.
 
diff --git a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_fr.properties
index 271a5b4d3ba923279049f1933b07e6a7ff84c816..b34fdf6d533f74c9a9d1c7a9293b861d29ba296e 100644
--- a/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/modules/bigbluebutton/ui/_i18n/LocalStrings_fr.properties
@@ -4,7 +4,7 @@ add.meeting=Ajouter un meeting
 add.template=Ajouter un mod\u00E8le
 admin.menu.title=BigBlueButton
 admin.menu.title.alt=BigBlueButton
-bigbluebutton.intro=Intro
+bigbluebutton.intro=Configuration de BigBlueButton, solution de conférences en ligne
 bigbluebutton.module.enabled=Module "BigBlueButton"
 bigbluebutton.module.enabled.for=Activer pour
 bigbluebutton.module.enabled.for.courses=Cours
diff --git a/src/main/resources/database/mysql/alter_14_2_x_to_14_2_5.sql b/src/main/resources/database/mysql/alter_14_2_x_to_14_2_5.sql
index 5f7ca8b2ecd8d8b816a955f3a65040caf8e75810..8ee52760d872ab0038c99264580a1445414a0e57 100644
--- a/src/main/resources/database/mysql/alter_14_2_x_to_14_2_5.sql
+++ b/src/main/resources/database/mysql/alter_14_2_x_to_14_2_5.sql
@@ -6,6 +6,7 @@ create table o_bbb_template (
    b_description varchar(2000) default null,
    b_system bool default false not null,
    b_external_id varchar(255) default null,
+   b_max_concurrent_meetings int default null,
    b_max_participants int default null,
    b_mute_on_start bool default null,
    b_auto_start_recording bool default null,
diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql
index 5d690dd81732d3fd739475e6604af6dea3eb743c..e86cafd52bed91f0aead14a530ac987e55401c29 100644
--- a/src/main/resources/database/mysql/setupDatabase.sql
+++ b/src/main/resources/database/mysql/setupDatabase.sql
@@ -1226,6 +1226,7 @@ create table o_bbb_template (
    b_description varchar(2000) default null,
    b_system bool default false not null,
    b_external_id varchar(255) default null,
+   b_max_concurrent_meetings int default null,
    b_max_participants int default null,
    b_mute_on_start bool default null,
    b_auto_start_recording bool default null,
diff --git a/src/main/resources/database/oracle/alter_14_2_x_to_14_2_5.sql b/src/main/resources/database/oracle/alter_14_2_x_to_14_2_5.sql
index b9a23fcb51c11e762de568b4c286df7efadaf3d3..54f3de70ad518fdddbbf93fc7c28354ed2a5531b 100644
--- a/src/main/resources/database/oracle/alter_14_2_x_to_14_2_5.sql
+++ b/src/main/resources/database/oracle/alter_14_2_x_to_14_2_5.sql
@@ -6,6 +6,7 @@ create table o_bbb_template (
    b_description varchar(2000) default null,
    b_system number default 0 not null,
    b_external_id varchar(255) default null,
+   b_max_concurrent_meetings int default null,
    b_max_participants int default null,
    b_mute_on_start number default null,
    b_auto_start_recording number default null,
diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql
index 23ea493ed59a154409ea8dc2f2ce1a8222bcc79b..98c4c3d7eefbf74d3f20db9450e3ee7cc5ee2a96 100644
--- a/src/main/resources/database/oracle/setupDatabase.sql
+++ b/src/main/resources/database/oracle/setupDatabase.sql
@@ -1292,6 +1292,7 @@ create table o_bbb_template (
    b_description varchar(2000) default null,
    b_system number default 0 not null,
    b_external_id varchar(255) default null,
+   b_max_concurrent_meetings int default null,
    b_max_participants int default null,
    b_mute_on_start number default null,
    b_auto_start_recording number default null,
diff --git a/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_5.sql b/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_5.sql
index 150c4e68f4e76d91ecdd5d2a2b0beeaf8a48fd63..ea80879cd6097a4a1b54c63d87cb8e9a5079041e 100644
--- a/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_5.sql
+++ b/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_5.sql
@@ -6,7 +6,8 @@ create table o_bbb_template (
    b_description varchar(2000) default null,
    b_system bool default false not null,
    b_external_id varchar(255) default null,
-   b_max_participants int default null,
+   b_max_concurrent_meetings int default null,
+   b_max_participants int8 default null,
    b_mute_on_start bool default null,
    b_auto_start_recording bool default null,
    b_allow_start_stop_recording bool default null,
diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql
index f0f5d3d571639fee50bd250cab1c3c7953ccdd32..8aa8395f4db215c258ffa95aa92d156885c4f14f 100644
--- a/src/main/resources/database/postgresql/setupDatabase.sql
+++ b/src/main/resources/database/postgresql/setupDatabase.sql
@@ -1251,6 +1251,7 @@ create table o_bbb_template (
    b_description varchar(2000) default null,
    b_system bool default false not null,
    b_external_id varchar(255) default null,
+   b_max_concurrent_meetings int default null,
    b_max_participants int default null,
    b_mute_on_start bool default null,
    b_auto_start_recording bool default null,
diff --git a/src/test/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAOTest.java b/src/test/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAOTest.java
index 2d775381127aec9cab87e5802d1383f288af0725..8adeda0b061c6d32a70199320e0f1f65bdc5cf7e 100644
--- a/src/test/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAOTest.java
+++ b/src/test/java/org/olat/modules/bigbluebutton/manager/BigBlueButtonMeetingDAOTest.java
@@ -19,14 +19,19 @@
  */
 package org.olat.modules.bigbluebutton.manager;
 
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.olat.commons.calendar.CalendarUtils;
 import org.olat.core.commons.persistence.DB;
+import org.olat.group.BusinessGroup;
+import org.olat.group.manager.BusinessGroupDAO;
 import org.olat.modules.bigbluebutton.BigBlueButtonMeeting;
+import org.olat.modules.bigbluebutton.BigBlueButtonMeetingTemplate;
 import org.olat.repository.RepositoryEntry;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
@@ -43,7 +48,11 @@ public class BigBlueButtonMeetingDAOTest extends OlatTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private BusinessGroupDAO businessGroupDao;
+	@Autowired
 	private BigBlueButtonMeetingDAO bigBlueButtonMeetingDao;
+	@Autowired
+	private BigBlueButtonMeetingTemplateDAO bigBlueButtonMeetingTemplateDao;
 	
 	@Test
 	public void createMeetingForRepositoryEntry() {
@@ -123,5 +132,64 @@ public class BigBlueButtonMeetingDAOTest extends OlatTestCase {
 		Assert.assertEquals(1, meetings.size());
 		Assert.assertTrue(meetings.contains(meeting));
 	}
+	
+	@Test
+	public void getAllMeetings() {
+		String name = "BigBlueButton - 3";
+		BusinessGroup group = businessGroupDao.createAndPersist(null, "BBB group", "bbb-desc", -1, -1, false, false, false, false, false);
+		BigBlueButtonMeeting meeting = bigBlueButtonMeetingDao.createAndPersistMeeting(name, null, null, group);
+		dbInstance.commit();
+		
+		List<BigBlueButtonMeeting> meetings = bigBlueButtonMeetingDao.getAllMeetings();
+		Assert.assertNotNull(meetings);
+		Assert.assertEquals(1, meetings.size());
+		Assert.assertTrue(meetings.contains(meeting));
+	}
+	
+	@Test
+	public void getConcurrentMeetings() {
+		String externalId = UUID.randomUUID().toString();
+		BigBlueButtonMeetingTemplate template = bigBlueButtonMeetingTemplateDao.createTemplate("A new template", externalId, false);
+		template.setMaxConcurrentMeetings(2);
+		template = bigBlueButtonMeetingTemplateDao.updateTemplate(template);
+		dbInstance.commit();
+		
+		BusinessGroup group = businessGroupDao.createAndPersist(null, "BBB group", "bbb-desc", -1, -1, false, false, false, false, false);
+		createMeeting("BigBlueButton - 4", date(1, 12), 15, date(1, 14), 15, template, group);
+		createMeeting("BigBlueButton - 5", date(1, 10), 120, date(1, 18), 120, template, group);
+		createMeeting("BigBlueButton - 6", date(1, 14), 0, date(1, 19), 0, template, group);
+		createMeeting("BigBlueButton - 7", date(2, 12), 15, date(2, 15), 15, template, group);
+		dbInstance.commit();
 
+		int concurrent = bigBlueButtonMeetingDao.getConcurrentMeetings(template, date(1, 15), date(1, 19));
+		Assert.assertEquals(2, concurrent);
+		
+		int concurrentFollowup = bigBlueButtonMeetingDao.getConcurrentMeetings(template, date(1, 20), date(1, 21));
+		Assert.assertEquals(1, concurrentFollowup);
+		
+		int concurrentWidePeriod = bigBlueButtonMeetingDao.getConcurrentMeetings(template, date(0, 10), date(3, 21));
+		Assert.assertEquals(4, concurrentWidePeriod);
+		
+		int concurrentWithin = bigBlueButtonMeetingDao.getConcurrentMeetings(template, date(2, 13), date(2, 14));
+		Assert.assertEquals(1, concurrentWithin);
+	}
+	
+	private BigBlueButtonMeeting createMeeting(String name, Date start, int leadTime, Date end, int followupTime,
+			BigBlueButtonMeetingTemplate template, BusinessGroup group) {
+		BigBlueButtonMeeting meeting = bigBlueButtonMeetingDao.createAndPersistMeeting(name, null, null, group);
+		meeting.setStartDate(start);
+		meeting.setLeadTime(leadTime);
+		meeting.setEndDate(end);
+		meeting.setFollowupTime(followupTime);
+		meeting.setTemplate(template);
+		return bigBlueButtonMeetingDao.updateMeeting(meeting);
+	}
+	
+	private Date date(int addDays, int hour) {
+		Calendar cal = Calendar.getInstance();
+		cal = CalendarUtils.getStartOfDay(cal);
+		cal.add(Calendar.DATE, addDays);
+		cal.set(Calendar.HOUR, hour);
+		return cal.getTime();
+	}
 }