diff --git a/src/main/java/org/olat/course/nodes/appointments/AppointmentsSecurityCallbackFactory.java b/src/main/java/org/olat/course/nodes/appointments/AppointmentsSecurityCallbackFactory.java
index 6bfc8edd3a594aa908d169d3c60dfe16ce38bccf..7473b9f150270e47dd27698344a6083145b92988 100644
--- a/src/main/java/org/olat/course/nodes/appointments/AppointmentsSecurityCallbackFactory.java
+++ b/src/main/java/org/olat/course/nodes/appointments/AppointmentsSecurityCallbackFactory.java
@@ -74,11 +74,6 @@ public class AppointmentsSecurityCallbackFactory {
 			return admin || coachCanEditTopic;
 		}
 
-		@Override
-		public Identity getDefaultOrganizer() {
-			return coachCanEditTopic? identity: null;
-		}
-
 		@Override
 		public boolean canEditTopic(List<Organizer> organizers) {
 			if (readOnly) return false;
diff --git a/src/main/java/org/olat/modules/appointments/AppointmentsSecurityCallback.java b/src/main/java/org/olat/modules/appointments/AppointmentsSecurityCallback.java
index 843df6ec6ded6f9fc3c94960baef37a03f4fb765..438ede5aeda0d3a488b5279cf7446e152bbbc5fc 100644
--- a/src/main/java/org/olat/modules/appointments/AppointmentsSecurityCallback.java
+++ b/src/main/java/org/olat/modules/appointments/AppointmentsSecurityCallback.java
@@ -21,8 +21,6 @@ package org.olat.modules.appointments;
 
 import java.util.List;
 
-import org.olat.core.id.Identity;
-
 /**
  * 
  * Initial date: 13 Apr 2020<br>
@@ -35,8 +33,6 @@ public interface AppointmentsSecurityCallback {
 	
 	public boolean canCreateTopic();
 	
-	public Identity getDefaultOrganizer();
-
 	public boolean canEditTopic(List<Organizer> organizers);
 	
 	public boolean canViewAppointment(List<Organizer> organizers);
diff --git a/src/main/java/org/olat/modules/appointments/AppointmentsSecurityCallbackFactory.java b/src/main/java/org/olat/modules/appointments/AppointmentsSecurityCallbackFactory.java
deleted file mode 100644
index 16fd58049028d94fdddf6ba013f9c76757022712..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/appointments/AppointmentsSecurityCallbackFactory.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * <a href="http://www.openolat.org">
- * OpenOLAT - Online Learning and Training</a><br>
- * <p>
- * Licensed under the Apache License, Version 2.0 (the "License"); <br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at the
- * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
- * <p>
- * Unless required by applicable law or agreed to in writing,<br>
- * software distributed under the License is distributed on an "AS IS" BASIS, <br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
- * See the License for the specific language governing permissions and <br>
- * limitations under the License.
- * <p>
- * Initial code contributed and copyrighted by<br>
- * frentix GmbH, http://www.frentix.com
- * <p>
- */
-package org.olat.modules.appointments;
-
-import java.util.List;
-
-import org.olat.core.id.Identity;
-import org.olat.course.nodes.AppointmentsCourseNode;
-import org.olat.course.run.userview.UserCourseEnvironment;
-import org.olat.modules.ModuleConfiguration;
-
-/**
- * 
- * Initial date: 13 Apr 2020<br>
- * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
- *
- */
-public class AppointmentsSecurityCallbackFactory {
-	
-	public static final AppointmentsSecurityCallback create(ModuleConfiguration config,
-			UserCourseEnvironment userCourseEnv) {
-		return new UserAppointmentsSecurityCallback(config, userCourseEnv);
-	}
-	
-	private static class UserAppointmentsSecurityCallback implements AppointmentsSecurityCallback {
-
-		private final Identity identity;
-		private final boolean admin;
-		private final boolean coach;
-		private final boolean coachCanEditTopic;
-		private final boolean coachCanEditAppointment;
-		private final boolean participant;
-		private final boolean readOnly;
-
-		public UserAppointmentsSecurityCallback(ModuleConfiguration config, UserCourseEnvironment userCourseEnv) {
-			this.identity = userCourseEnv.getIdentityEnvironment().getIdentity();
-			this.admin = userCourseEnv.isAdmin();
-			this.coach = userCourseEnv.isCoach();
-			this.participant = userCourseEnv.isParticipant();
-			this.readOnly = userCourseEnv.isCourseReadOnly();
-			
-			this.coachCanEditTopic = coach && config.getBooleanSafe(AppointmentsCourseNode.CONFIG_COACH_EDIT_TOPIC);
-			this.coachCanEditAppointment = coach && config.getBooleanSafe(AppointmentsCourseNode.CONFIG_COACH_EDIT_APPOINTMENT);
-		}
-
-		@Override
-		public boolean canEditTopics() {
-			return admin;
-		}
-
-		@Override
-		public boolean canCreateTopic() {
-			if (readOnly) return false;
-			
-			return admin || coachCanEditTopic;
-		}
-
-		@Override
-		public Identity getDefaultOrganizer() {
-			return coachCanEditTopic? identity: null;
-		}
-
-		@Override
-		public boolean canEditTopic(List<Organizer> organizers) {
-			if (readOnly) return false;
-			
-			return admin || (coachCanEditTopic && isOrganizer(organizers));
-		}
-
-		@Override
-		public boolean canViewAppointment(List<Organizer> organizers) {
-			return admin || (coach && isOrganizer(organizers));
-		}
-
-		@Override
-		public boolean canEditAppointment(List<Organizer> organizers) {
-			return admin || (coachCanEditAppointment && isOrganizer(organizers));
-		}
-
-		@Override
-		public boolean canSelectAppointments() {
-			if (readOnly) return false;
-			
-			return participant;
-		}
-		
-		private boolean isOrganizer(List<Organizer> organizers) {
-			return organizers.stream()
-					.anyMatch(o -> o.getIdentity().getKey().equals(identity.getKey()));
-		}
-		
-	}
-
-}
diff --git a/src/main/java/org/olat/modules/appointments/AppointmentsService.java b/src/main/java/org/olat/modules/appointments/AppointmentsService.java
index 0597009cc72bfa68a1e1fd371522aea165e0681c..43337edf99571978647d1f319a40e5470403e41f 100644
--- a/src/main/java/org/olat/modules/appointments/AppointmentsService.java
+++ b/src/main/java/org/olat/modules/appointments/AppointmentsService.java
@@ -59,9 +59,7 @@ public interface AppointmentsService {
 	 */
 	public List<Topic> getRestictedTopic(RepositoryEntryRef entry, String subIdent, IdentityRef identity);
 	
-	public Organizer createOrganizer(Topic topic, Identity identity);
-
-	public void deleteOrganizers(TopicRef topic, Collection<Organizer> organizers);
+	public void updateOrganizers(Topic topic, Collection<Identity> identities);
 
 	public List<Organizer> getOrganizers(TopicRef topic);
 
diff --git a/src/main/java/org/olat/modules/appointments/manager/AppointmentsServiceImpl.java b/src/main/java/org/olat/modules/appointments/manager/AppointmentsServiceImpl.java
index 7c4a9dd620f449b49cca2de4b6730cf9f45b9c2d..3489742990b012333f66a5fac7d7959044b7313b 100644
--- a/src/main/java/org/olat/modules/appointments/manager/AppointmentsServiceImpl.java
+++ b/src/main/java/org/olat/modules/appointments/manager/AppointmentsServiceImpl.java
@@ -198,10 +198,48 @@ public class AppointmentsServiceImpl implements AppointmentsService {
 			groupDao.removeGroup(group);
 		}
 	}
-
+	
 	@Override
-	public Organizer createOrganizer(Topic topic, Identity identity) {
-		Organizer createOrganizer = organizerDao.createOrganizer(topic, identity);
+	public void updateOrganizers(Topic topic, Collection<Identity> identities) {
+		List<Organizer> organizers = organizerDao.loadOrganizers(topic);
+		List<Identity> organizersToCreate = new ArrayList<>(identities.size());
+		for (Identity identity : identities) {
+			boolean found = false;
+			for (Organizer organizer : organizers) {
+				if (organizer.getIdentity().equals(identity)) {
+					found = true;
+					break;
+				}
+			}
+			
+			if (!found) {
+				organizersToCreate.add(identity);
+			}
+		}
+		
+		if (!organizersToCreate.isEmpty()) {
+			List<Organizer> createdOrganizers = createOrganizers(topic, organizersToCreate);
+			organizers.addAll(createdOrganizers);
+		}
+		
+		ArrayList<Organizer> organizersToDelete = new ArrayList<>(organizers.size());
+		for (Iterator<Organizer> organizersIt = organizers.iterator(); organizersIt.hasNext(); ) {
+			Organizer organizer = organizersIt.next();
+			if (!identities.contains(organizer.getIdentity())) {
+				organizersToDelete.add(organizer);
+			}
+		}
+		if (!organizersToDelete.isEmpty()) {
+			deleteOrganizers(topic, organizersToDelete);
+		}
+	}
+
+	private List<Organizer> createOrganizers(Topic topic, Collection<Identity> identities) {
+		List<Organizer> organizers = new ArrayList<>(identities.size());
+		for (Identity identity : identities) {
+			Organizer organizer = organizerDao.createOrganizer(topic, identity);
+			organizers.add(organizer);
+		}
 		
 		AppointmentSearchParams params = new AppointmentSearchParams();
 		params.setTopic(topic);
@@ -210,13 +248,15 @@ public class AppointmentsServiceImpl implements AppointmentsService {
 			params.setStatus(Status.confirmed);
 		}
 		List<Appointment> appointments = appointmentDao.loadAppointments(params);
-		calendarSyncher.syncCalendar(appointments, identity);
 		
-		return createOrganizer;
+		for (Organizer organizer : organizers) {
+			calendarSyncher.syncCalendar(appointments, organizer.getIdentity());
+		}
+		
+		return organizers;
 	}
 
-	@Override
-	public void deleteOrganizers(TopicRef topic, Collection<Organizer> organizers) {
+	private void deleteOrganizers(TopicRef topic, Collection<Organizer> organizers) {
 		AppointmentSearchParams params = new AppointmentSearchParams();
 		params.setTopic(topic);
 		params.setStatus(Status.confirmed);
diff --git a/src/main/java/org/olat/modules/appointments/ui/TopicCreateController.java b/src/main/java/org/olat/modules/appointments/ui/TopicCreateController.java
index 4ef345aa1a6545f5b73502d7fe96ba606b9c27ca..f3a65eea1a29d56f2c4e22de43486a9ad0b695c8 100644
--- a/src/main/java/org/olat/modules/appointments/ui/TopicCreateController.java
+++ b/src/main/java/org/olat/modules/appointments/ui/TopicCreateController.java
@@ -29,7 +29,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.olat.basesecurity.GroupRoles;
@@ -55,7 +54,6 @@ import org.olat.core.util.StringHelper;
 import org.olat.modules.appointments.Appointment;
 import org.olat.modules.appointments.AppointmentsSecurityCallback;
 import org.olat.modules.appointments.AppointmentsService;
-import org.olat.modules.appointments.Organizer;
 import org.olat.modules.appointments.Topic;
 import org.olat.modules.appointments.Topic.Type;
 import org.olat.repository.RepositoryEntry;
@@ -94,7 +92,6 @@ public class TopicCreateController extends FormBasicController {
 	private String subIdent;
 	private AppointmentsSecurityCallback secCallback;
 	private Topic topic;
-	private List<Organizer> organizers;
 	private List<Identity> coaches;
 	private List<AppointmentWrapper> appointmentWrappers;
 	private boolean multiParticipationsSelected = true;
@@ -115,7 +112,6 @@ public class TopicCreateController extends FormBasicController {
 		this.entry = entry;
 		this.subIdent = subIdent;
 		
-		organizers = new ArrayList<>(0);
 		coaches = repositoryService.getMembers(entry, RepositoryEntryRelationType.all, GroupRoles.coach.name());
 		
 		initForm(ureq);
@@ -153,13 +149,14 @@ public class TopicCreateController extends FormBasicController {
 		}
 		coachesKV.sort(VALUE_ASC);
 		organizerEl = uifactory.addCheckboxesDropdown("organizer", "organizer", formLayout, coachesKV.keys(), coachesKV.values());
-		for (Organizer organizer : organizers) {
-			Long organizerKey = organizer.getIdentity().getKey();
-			if (coaches.stream().anyMatch(coach -> organizerKey.equals(coach.getKey()))) {
-				organizerEl.select(organizerKey.toString(), true);
+		organizerEl.setVisible(!coaches.isEmpty());
+		
+		if (organizerEl.isVisible()) {
+			String defaultOrganizerKey = getIdentity().getKey().toString();
+			if (organizerEl.getKeys().contains(defaultOrganizerKey)) {
+					organizerEl.select(defaultOrganizerKey, true);
 			}
 		}
-		organizerEl.setVisible(!coaches.isEmpty());
 		
 		// Appointments
 		locationEl = uifactory.addTextElement("appointment.location", 128, null, formLayout);
@@ -369,10 +366,6 @@ public class TopicCreateController extends FormBasicController {
 
 	private void doSaveTopic() {
 		topic = appointmentsService.createTopic(entry, subIdent);
-		Identity organizer = secCallback.getDefaultOrganizer();
-		if (organizer != null) {
-			appointmentsService.createOrganizer(topic, organizer);
-		}
 		
 		String title = titleEl.getValue();
 		topic.setTitle(title);
@@ -397,21 +390,10 @@ public class TopicCreateController extends FormBasicController {
 
 	private void doSaveOrganizers() {
 		Collection<String> selectedOrganizerKeys = organizerEl.getSelectedKeys();
-		
-		// delete unselected
-		List<Organizer> organizersToDelete = organizers.stream()
-				.filter(organizer -> !selectedOrganizerKeys.contains(organizer.getIdentity().getKey().toString()))
+		List<Identity> selectedOrganizers = coaches.stream()
+				.filter(i -> selectedOrganizerKeys.contains(i.getKey().toString()))
 				.collect(Collectors.toList());
-		appointmentsService.deleteOrganizers(topic, organizersToDelete);
-		
-		// create newly selected
-		Set<String> currentOrganizerKeys = organizers.stream()
-				.map(o -> o.getIdentity().getKey().toString())
-				.collect(Collectors.toSet());
-		selectedOrganizerKeys.removeAll(currentOrganizerKeys);
-		coaches.stream()
-				.filter(coach -> selectedOrganizerKeys.contains(coach.getKey().toString()))
-				.forEach(coach -> appointmentsService.createOrganizer(topic, coach));
+		appointmentsService.updateOrganizers(topic, selectedOrganizers);
 	}
 
 	private void doSaveSingleAppointments() {
diff --git a/src/main/java/org/olat/modules/appointments/ui/TopicEditController.java b/src/main/java/org/olat/modules/appointments/ui/TopicEditController.java
index 900936f6bbbab1aaac7822bb97af5e269e498986..e8817c263bd110c1d958ca674b686f0fca2f1fef 100644
--- a/src/main/java/org/olat/modules/appointments/ui/TopicEditController.java
+++ b/src/main/java/org/olat/modules/appointments/ui/TopicEditController.java
@@ -25,7 +25,6 @@ import static org.olat.core.util.ArrayHelper.emptyStrings;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.olat.basesecurity.GroupRoles;
@@ -241,21 +240,10 @@ public class TopicEditController extends FormBasicController {
 	
 	private void doSaveOrgianzers() {
 		Collection<String> selectedOrganizerKeys = organizerEl.getSelectedKeys();
-		
-		// delete unselected
-		List<Organizer> organizersToDelete = organizers.stream()
-				.filter(organizer -> !selectedOrganizerKeys.contains(organizer.getIdentity().getKey().toString()))
+		List<Identity> selectedOrganizers = coaches.stream()
+				.filter(i -> selectedOrganizerKeys.contains(i.getKey().toString()))
 				.collect(Collectors.toList());
-		appointmentsService.deleteOrganizers(topic, organizersToDelete);
-		
-		// create newly selected
-		Set<String> currentOrganizerKeys = organizers.stream()
-				.map(o -> o.getIdentity().getKey().toString())
-				.collect(Collectors.toSet());
-		selectedOrganizerKeys.removeAll(currentOrganizerKeys);
-		coaches.stream()
-				.filter(coach -> selectedOrganizerKeys.contains(coach.getKey().toString()))
-				.forEach(coach -> appointmentsService.createOrganizer(topic, coach));
+		appointmentsService.updateOrganizers(topic, selectedOrganizers);
 	}
 	
 	private boolean isConfigChanged() {
diff --git a/src/test/java/org/olat/modules/appointments/AppointmentsServiceTest.java b/src/test/java/org/olat/modules/appointments/AppointmentsServiceTest.java
index 34dd3ec2ec22e128f757589251b861f0a8365f4d..992c455d951182197907d1114e4cd7a5ebd438ae 100644
--- a/src/test/java/org/olat/modules/appointments/AppointmentsServiceTest.java
+++ b/src/test/java/org/olat/modules/appointments/AppointmentsServiceTest.java
@@ -53,6 +53,29 @@ public class AppointmentsServiceTest extends OlatTestCase {
 	@Autowired
 	private AppointmentsService sut;
 	
+	@Test
+	public void shouldUpdateOrganizers() {
+		Identity organizerDelete = JunitTestHelper.createAndPersistIdentityAsRndUser("ap");
+		Identity organizerKeep = JunitTestHelper.createAndPersistIdentityAsRndUser("ap");
+		Identity organizerNew1 = JunitTestHelper.createAndPersistIdentityAsRndUser("ap");
+		Identity organizerNew2 = JunitTestHelper.createAndPersistIdentityAsRndUser("ap");
+		Topic topic = createRandomTopic();
+		sut.updateOrganizers(topic, asList(organizerDelete, organizerKeep));
+		dbInstance.commitAndCloseSession();
+		
+		sut.updateOrganizers(topic, asList(organizerKeep, organizerNew1, organizerNew2));
+		dbInstance.commitAndCloseSession();
+		
+		List<Organizer> organizers = sut.getOrganizers(topic);
+		assertThat(organizers).extracting(Organizer::getIdentity)
+				.containsExactlyInAnyOrder(
+						organizerKeep,
+						organizerNew1,
+						organizerNew2)
+				.doesNotContain(
+						organizerDelete);
+	}
+	
 	@Test
 	public void createParticipationShouldCreateParticiption() {
 		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("ap");