diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java b/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java
index 0ff48402cc7b909f8219e88a1dfc80d9087de34d..f23e2a1acf644b1b1c2304dd3cd714e3f7fa244c 100644
--- a/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java
+++ b/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java
@@ -30,6 +30,7 @@ import static org.olat.restapi.security.RestSecurityHelper.isAuthor;
 import static org.olat.restapi.security.RestSecurityHelper.isAuthorEditor;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
@@ -210,7 +211,30 @@ public class RepositoryEntryResource {
 			repositoryManager.addOwners(ureq.getIdentity(), iae, repoEntry);
 			return Response.ok().build();
 		} catch (Exception e) {
-			e.printStackTrace();
+			log.error("Trying to add an owner to a repository entry", e);
+			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}
+	}
+	
+	@PUT
+	@Path("owners")
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response addOwners(UserVO[] owners, @PathParam("repoEntryKey") String repoEntryKey,
+			@Context HttpServletRequest request) {
+		try {
+			RepositoryEntry repoEntry = lookupRepositoryEntry(repoEntryKey);
+			if(repoEntry == null) {
+				return Response.serverError().status(Status.NOT_FOUND).build();
+			} else if(!isAuthorEditor(repoEntry, request)) {
+				return Response.serverError().status(Status.UNAUTHORIZED).build();
+			}
+			
+			List<Identity> identityToAdd = loadIdentities(owners);
+			UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+			IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
+			repositoryManager.addOwners(ureq.getIdentity(), iae, repoEntry);
+			return Response.ok().build();
+		} catch (Exception e) {
 			log.error("Trying to add an owner to a repository entry", e);
 			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
 		}
@@ -311,6 +335,30 @@ public class RepositoryEntryResource {
 			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
 		}
 	}
+
+	@PUT
+	@Path("coaches")
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response addCoach(UserVO[] coaches, @PathParam("repoEntryKey") String repoEntryKey,
+			@Context HttpServletRequest request) {
+		try {
+			RepositoryEntry repoEntry = lookupRepositoryEntry(repoEntryKey);
+			if(repoEntry == null) {
+				return Response.serverError().status(Status.NOT_FOUND).build();
+			} else if(!isAuthorEditor(repoEntry, request)) {
+				return Response.serverError().status(Status.UNAUTHORIZED).build();
+			}
+			
+			List<Identity> identityToAdd = loadIdentities(coaches);
+			UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+			IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
+			repositoryManager.addTutors(ureq.getIdentity(), ureq.getUserSession().getRoles(), iae, repoEntry, null);
+			return Response.ok().build();
+		} catch (Exception e) {
+			log.error("Trying to add a coach to a repository entry", e);
+			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}
+	}
 	
 	/**
 	 * Removes the coach from the repository entry.
@@ -408,6 +456,38 @@ public class RepositoryEntryResource {
 		}
 	}
 	
+	@PUT
+	@Path("participants")
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response addParticipants(UserVO[] participants, @PathParam("repoEntryKey") String repoEntryKey,
+			@Context HttpServletRequest request) {
+		try {
+			RepositoryEntry repoEntry = lookupRepositoryEntry(repoEntryKey);
+			if(repoEntry == null) {
+				return Response.serverError().status(Status.NOT_FOUND).build();
+			} else if(!isAuthorEditor(repoEntry, request)) {
+				return Response.serverError().status(Status.UNAUTHORIZED).build();
+			}
+			
+			List<Identity> participantList = loadIdentities(participants);
+			UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+			IdentitiesAddEvent iae = new IdentitiesAddEvent(participantList);
+			repositoryManager.addParticipants(ureq.getIdentity(), ureq.getUserSession().getRoles(), iae, repoEntry, null);
+			return Response.ok().build();
+		} catch (Exception e) {
+			log.error("Trying to add a participant to a repository entry", e);
+			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		}
+	}
+	
+	private List<Identity> loadIdentities(UserVO[] users) {
+		List<Long> identityKeys = new ArrayList<>();
+		for(UserVO user:users) {
+			identityKeys.add(user.getKey());
+		}
+		return securityManager.loadIdentityByKeys(identityKeys);
+	}
+	
 	/**
 	 * Removes the participant from the repository entry.
 	 * @response.representation.200.doc The user is removed as participant from the repository entry
diff --git a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
index c427210ccddbf191069d5052a08a97c39e590afa..43d9a033488958de663a8bd2e3bb24b94d0f124d 100644
--- a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
@@ -25,6 +25,7 @@ import static org.olat.restapi.security.RestSecurityHelper.isAdmin;
 import static org.olat.restapi.security.RestSecurityHelper.isAuthor;
 import static org.olat.restapi.security.RestSecurityHelper.isAuthorEditor;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
@@ -251,9 +252,8 @@ public class CourseWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 
-		RepositoryManager rm = RepositoryManager.getInstance();
 		RepositoryService rs = CoreSpringFactory.getImpl(RepositoryService.class);
-		RepositoryEntry re = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry re = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		if (re == null) {
 			return Response.serverError().status(Status.NOT_FOUND).build();
 		}
@@ -318,10 +318,10 @@ public class CourseWebService {
 		} else if (!isAuthorEditor(course, request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
+		
 		UserRequest ureq = getUserRequest(request);
-		RepositoryManager rm = RepositoryManager.getInstance();
 		RepositoryService rs = CoreSpringFactory.getImpl(RepositoryService.class);
-		RepositoryEntry re = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry re = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		
 		ErrorList errors = rs.delete(re, ureq.getIdentity(), ureq.getUserSession().getRoles(), ureq.getLocale());
 		if(errors.hasErrors()) {
@@ -490,8 +490,7 @@ public class CourseWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		RepositoryManager rm = RepositoryManager.getInstance();
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class);
 		List<Identity> owners = repositoryService.getMembers(repositoryEntry, GroupRoles.owner.name());
 		
@@ -521,8 +520,7 @@ public class CourseWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		RepositoryManager rm = RepositoryManager.getInstance();
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class);
 		List<Identity> coachList = repositoryService.getMembers(repositoryEntry, GroupRoles.coach.name());
 		
@@ -552,8 +550,7 @@ public class CourseWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		RepositoryManager rm = RepositoryManager.getInstance();
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class);
 		List<Identity> participantList = repositoryService.getMembers(repositoryEntry, GroupRoles.participant.name());
 		
@@ -585,9 +582,8 @@ public class CourseWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		RepositoryManager rm = RepositoryManager.getInstance();
 		RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class);
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		
 		BaseSecurity securityManager = BaseSecurityManager.getInstance();
 		SecurityGroup authorGroup = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
@@ -636,7 +632,7 @@ public class CourseWebService {
 		
 		//add the author as owner of the course
 		RepositoryManager rm = RepositoryManager.getInstance();
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		List<Identity> authors = Collections.singletonList(author);
 		IdentitiesAddEvent identitiesAddedEvent = new IdentitiesAddEvent(authors);
 		rm.addOwners(identity, identitiesAddedEvent, repositoryEntry);
@@ -644,6 +640,35 @@ public class CourseWebService {
 		return Response.ok().build();
 	}
 	
+	@PUT
+	@Path("authors")
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response addAuthors(UserVO[] authors, @Context HttpServletRequest httpRequest) {
+		if (!isAuthorEditor(course, httpRequest)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+
+		BaseSecurity securityManager = BaseSecurityManager.getInstance();
+		List<Identity> authorList = loadIdentities(authors);
+		Identity identity = getIdentity(httpRequest);
+
+		SecurityGroup authorGroup = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
+		for(Identity author:authorList) {
+			boolean hasBeenAuthor = securityManager.isIdentityInSecurityGroup(author, authorGroup);
+			if(!hasBeenAuthor) {
+				//not an author already, add this identity to the security group "authors"
+				securityManager.addIdentityToSecurityGroup(author, authorGroup);
+				log.audit("User::" + identity.getName() + " added system role::" + Constants.GROUP_AUTHORS + " to user::" + author.getName() + " via addAuthor method in course REST API", null);
+			}
+		}
+		
+		//add the author as owner of the course
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		IdentitiesAddEvent identitiesAddedEvent = new IdentitiesAddEvent(authorList);
+		RepositoryManager.getInstance().addOwners(identity, identitiesAddedEvent, repositoryEntry);
+		return Response.ok().build();
+	}
+	
 	/**
 	 * Remove an owner and author to the course
 	 * @response.representation.200.doc The user was successfully removed as owner of the course
@@ -672,10 +697,9 @@ public class CourseWebService {
 		
 		//remove the author as owner of the course
 		RepositoryManager rm = RepositoryManager.getInstance();
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		List<Identity> authors = Collections.singletonList(author);
 		rm.removeOwners(identity, authors, repositoryEntry);
-		
 		return Response.ok().build();
 	}
 	
@@ -707,7 +731,7 @@ public class CourseWebService {
 		
 		//add the author as owner of the course
 		RepositoryManager rm = RepositoryManager.getInstance();
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		List<Identity> tutors = Collections.singletonList(tutor);
 		IdentitiesAddEvent iae = new IdentitiesAddEvent(tutors);
 		rm.addTutors(identity, ureq.getUserSession().getRoles(), iae, repositoryEntry, new MailPackage(false));
@@ -715,6 +739,26 @@ public class CourseWebService {
 		return Response.ok().build();
 	}
 	
+	@PUT
+	@Path("tutors")
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response addCoaches(UserVO[] coaches, @Context HttpServletRequest httpRequest) {
+		if (!isAuthorEditor(course, httpRequest)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		
+		List<Identity> coachList = loadIdentities(coaches);
+		Identity identity = getIdentity(httpRequest);
+		UserRequest ureq = getUserRequest(httpRequest);
+		
+		//add the author as owner of the course
+		RepositoryManager rm = RepositoryManager.getInstance();
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		IdentitiesAddEvent iae = new IdentitiesAddEvent(coachList);
+		rm.addTutors(identity, ureq.getUserSession().getRoles(), iae, repositoryEntry, new MailPackage(false));
+		return Response.ok().build();
+	}
+	
 	/**
 	 * Add an participant to the course
 	 * @response.representation.200.doc The user is a participant of the course
@@ -743,7 +787,7 @@ public class CourseWebService {
 		
 		//add the author as owner of the course
 		RepositoryManager rm = RepositoryManager.getInstance();
-		RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true);
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		List<Identity> participants = Collections.singletonList(participant);
 		IdentitiesAddEvent iae = new IdentitiesAddEvent(participants);
 		rm.addParticipants(identity, ureq.getUserSession().getRoles(), iae, repositoryEntry, new MailPackage(false));
@@ -751,6 +795,44 @@ public class CourseWebService {
 		return Response.ok().build();
 	}
 	
+	/**
+	 * Add an participant to the course
+	 * @response.representation.200.doc The user is a participant of the course
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The course or the user not found
+	 * @param identityKey The user identifier
+	 * @param httpRequest The HTTP request
+	 * @return It returns 200  if the user is added as owner and author of the course
+	 */
+	@PUT
+	@Path("participants")
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response addParticipants(UserVO[] participants,
+			@Context HttpServletRequest httpRequest) {
+		if (!isAuthorEditor(course, httpRequest)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+
+		List<Identity> participantList = loadIdentities(participants);
+		Identity identity = getIdentity(httpRequest);
+		UserRequest ureq = getUserRequest(httpRequest);
+		
+		//add the participants to the course
+		RepositoryManager rm = RepositoryManager.getInstance();
+		RepositoryEntry repositoryEntry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		IdentitiesAddEvent iae = new IdentitiesAddEvent(participantList);
+		rm.addParticipants(identity, ureq.getUserSession().getRoles(), iae, repositoryEntry, new MailPackage(false));
+		return Response.ok().build();
+	}
+	
+	private List<Identity> loadIdentities(UserVO[] users) {
+		List<Long> identityKeys = new ArrayList<>();
+		for(UserVO user:users) {
+			identityKeys.add(user.getKey());
+		}
+		return BaseSecurityManager.getInstance().loadIdentityByKeys(identityKeys);
+	}
+	
 	public static boolean isCourseAccessible(ICourse course, boolean authorRightsMandatory, HttpServletRequest request) {
 		if(isAdmin(request)) {
 			return true;
@@ -760,7 +842,7 @@ public class CourseWebService {
 		}
 
 		Identity identity = getIdentity(request);
-		RepositoryEntry entry = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
+		RepositoryEntry entry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 		ACService acManager = CoreSpringFactory.getImpl(ACService.class);
 		AccessResult result = acManager.isAccessible(entry, identity, false);
 		if(result.isAccessible()) {
diff --git a/src/test/java/org/olat/restapi/CourseTest.java b/src/test/java/org/olat/restapi/CourseTest.java
index 7f7d2b05cbdf6ea1c4dda4c4a19696463dbb38cf..9a7b82d0e49292383deab698bfc2e80248cf0654 100644
--- a/src/test/java/org/olat/restapi/CourseTest.java
+++ b/src/test/java/org/olat/restapi/CourseTest.java
@@ -78,6 +78,7 @@ import org.olat.restapi.support.vo.RepositoryEntryVO;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatJerseyTestCase;
 import org.olat.user.restapi.UserVO;
+import org.olat.user.restapi.UserVOFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
 public class CourseTest extends OlatJerseyTestCase {
@@ -232,7 +233,7 @@ public class CourseTest extends OlatJerseyTestCase {
 		List<String> courseType = new ArrayList<String>();
 		courseType.add(CourseModule.getCourseTypeName());
 		Roles roles = new Roles(true, true, true, true, false, true, false);
-		//fxdiff VCRP-1,2: access control of resources
+
 		SearchRepositoryEntryParameters params = new SearchRepositoryEntryParameters("*", "*", "*", courseType, null, roles, "");
 		List<RepositoryEntry> repoEntries = repositoryManager.genericANDQueryWithRolesRestriction(params, 0, -1, true);
 		assertNotNull(repoEntries);
@@ -243,29 +244,68 @@ public class CourseTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testAddAuthor() throws IOException, URISyntaxException {
-		assertTrue(conn.login("administrator", "openolat"));
+	public void addAuthor() throws IOException, URISyntaxException {
+		Assert.assertTrue(conn.login("administrator", "openolat"));
 		URI request = UriBuilder.fromUri(getContextURI()).path("/repo/courses/" + course1.getResourceableId() + "/authors/" + auth0.getKey()).build();
 		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
 		HttpResponse response = conn.execute(method);
-		assertEquals(200, response.getStatusLine().getStatusCode());
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
 		EntityUtils.consume(response.getEntity());
 
 		//is auth0 author
 		SecurityGroup authorGroup = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
 		boolean isAuthor = securityManager.isIdentityInSecurityGroup(auth0, authorGroup);
 		dbInstance.intermediateCommit();
-		assertTrue(isAuthor);
+		Assert.assertTrue(isAuthor);
 		
 		//is auth0 owner
 		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course1, true);
 		boolean isOwner = repositoryService.hasRole(auth0, repositoryEntry, GroupRoles.owner.name());
 		dbInstance.intermediateCommit();
-		assertTrue(isOwner);
+		Assert.assertTrue(isOwner);
+	}
+	
+	@Test
+	public void addAuthors() throws IOException, URISyntaxException {
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+		ICourse course = CoursesWebService.createEmptyCourse(admin, "course1", "course1 long name", null);
+		Identity author1 = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-auth-1");
+		Identity author2 = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-auth-2");
+		dbInstance.commitAndCloseSession();
+		
+		UserVO[] newAuthors = new UserVO[2];
+		newAuthors[0] = UserVOFactory.get(author1);
+		newAuthors[1] = UserVOFactory.get(author2);
+
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses")
+				.path(course.getResourceableId().toString()).path("authors").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, newAuthors);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+
+		//is auth0 author
+		SecurityGroup authorGroup = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
+		boolean isAuthor1 = securityManager.isIdentityInSecurityGroup(author1, authorGroup);
+		boolean isAuthor2 = securityManager.isIdentityInSecurityGroup(author2, authorGroup);
+		dbInstance.commit();
+		Assert.assertTrue(isAuthor1);
+		Assert.assertTrue(isAuthor2);
+		
+		//is auth0 owner
+		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course, true);
+		boolean isOwner1 = repositoryService.hasRole(author1, repositoryEntry, GroupRoles.owner.name());
+		boolean isOwner2 = repositoryService.hasRole(author2, repositoryEntry, GroupRoles.owner.name());
+		dbInstance.commit();
+		Assert.assertTrue(isOwner1);
+		Assert.assertTrue(isOwner2);
 	}
 	
 	@Test
-	public void testGetAuthors() throws IOException, URISyntaxException {
+	public void getAuthors() throws IOException, URISyntaxException {
 		//make auth1 and auth2 authors
 		SecurityGroup authorGroup = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
 		if(!securityManager.isIdentityInSecurityGroup(auth1, authorGroup)) {
@@ -299,7 +339,7 @@ public class CourseTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testRemoveAuthor() throws IOException, URISyntaxException {
+	public void removeAuthor() throws IOException, URISyntaxException {
 		//make auth1 and auth2 authors
 		SecurityGroup authorGroup = securityManager.findSecurityGroupByName(Constants.GROUP_AUTHORS);
 		if(!securityManager.isIdentityInSecurityGroup(auth1, authorGroup)) {
@@ -342,7 +382,7 @@ public class CourseTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testGetTutors() throws IOException, URISyntaxException {
+	public void getTutors() throws IOException, URISyntaxException {
 		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("Course-coach");
 		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course1, true);
 		repositoryService.addRole(coach, repositoryEntry, GroupRoles.coach.name());
@@ -369,7 +409,7 @@ public class CourseTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testAddCoach() throws IOException, URISyntaxException {
+	public void addCoach() throws IOException, URISyntaxException {
 		assertTrue(conn.login("administrator", "openolat"));
 		URI request = UriBuilder.fromUri(getContextURI()).path("/repo/courses/" + course1.getResourceableId() + "/tutors/" + auth1.getKey()).build();
 		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
@@ -383,9 +423,40 @@ public class CourseTest extends OlatJerseyTestCase {
 		dbInstance.intermediateCommit();
 		assertTrue(isTutor);
 	}
+
+	@Test
+	public void addCoaches() throws IOException, URISyntaxException {
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+		ICourse course = CoursesWebService.createEmptyCourse(admin, "course1", "course1 long name", null);
+		Identity coach1 = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-coach-1");
+		Identity coach2 = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-coach-2");
+		dbInstance.commitAndCloseSession();
+		
+		//add the 2 participants to the course
+		UserVO[] newCoaches = new UserVO[2];
+		newCoaches[0] = UserVOFactory.get(coach1);
+		newCoaches[1] = UserVOFactory.get(coach2);
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses")
+				.path(course.getResourceableId().toString()).path("tutors").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, newCoaches);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+
+		//is auth0 coach/tutor
+		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course, true);
+		boolean isTutor1 = repositoryService.hasRole(coach1, repositoryEntry, GroupRoles.coach.name());
+		boolean isTutor2 = repositoryService.hasRole(coach2, repositoryEntry, GroupRoles.coach.name());
+		dbInstance.commit();
+		Assert.assertTrue(isTutor1);
+		Assert.assertTrue(isTutor2);
+	}
+	
 	
 	@Test
-	public void testGetParticipants() throws IOException, URISyntaxException {
+	public void getParticipants() throws IOException, URISyntaxException {
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Course-participant");
 		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course1, true);
 		repositoryService.addRole(participant, repositoryEntry, GroupRoles.participant.name());
@@ -412,7 +483,7 @@ public class CourseTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testAddParticipant() throws IOException, URISyntaxException {
+	public void addParticipant() throws IOException, URISyntaxException {
 		assertTrue(conn.login("administrator", "openolat"));
 		URI request = UriBuilder.fromUri(getContextURI()).path("/repo/courses/" + course1.getResourceableId() + "/participants/" + auth2.getKey()).build();
 		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
@@ -423,8 +494,38 @@ public class CourseTest extends OlatJerseyTestCase {
 		//is auth2 participant
 		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course1, true);
 		boolean isParticipant = repositoryService.hasRole(auth2, repositoryEntry, GroupRoles.participant.name());
-		dbInstance.intermediateCommit();
-		assertTrue(isParticipant);
+		dbInstance.commit();
+		Assert.assertTrue(isParticipant);
+	}
+	
+	@Test
+	public void addParticipants() throws IOException, URISyntaxException {
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+		ICourse course = CoursesWebService.createEmptyCourse(admin, "course1", "course1 long name", null);
+		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-part-1");
+		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("rest-part-2");
+		dbInstance.commitAndCloseSession();
+		
+		//add the 2 participants to the course
+		UserVO[] newParticipants = new UserVO[2];
+		newParticipants[0] = UserVOFactory.get(participant1);
+		newParticipants[1] = UserVOFactory.get(participant2);
+
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo").path("courses")
+				.path(course.getResourceableId().toString()).path("participants").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, newParticipants);
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		//check that they are course members
+		RepositoryEntry repositoryEntry = repositoryManager.lookupRepositoryEntry(course, true);
+		boolean isParticipant1 = repositoryService.hasRole(participant1, repositoryEntry, GroupRoles.participant.name());
+		boolean isParticipant2 = repositoryService.hasRole(participant2, repositoryEntry, GroupRoles.participant.name());
+		dbInstance.commit();
+		Assert.assertTrue(isParticipant1);
+		Assert.assertTrue(isParticipant2);
 	}
 	
 	protected List<UserVO> parseUserArray(InputStream body) {
diff --git a/src/test/java/org/olat/restapi/ForumTest.java b/src/test/java/org/olat/restapi/ForumTest.java
index 33b4f7894aad72105df19590486523cbdac01d06..6e75f8528afd33025a7c62b40bcf7bcf0b116542 100644
--- a/src/test/java/org/olat/restapi/ForumTest.java
+++ b/src/test/java/org/olat/restapi/ForumTest.java
@@ -416,7 +416,7 @@ public class ForumTest extends OlatJerseyTestCase {
 
 		URI uri = getForumUriBuilder().path("posts").path(m1.getKey().toString()).build();
 		HttpPut method = conn.createPut(uri, MediaType.APPLICATION_JSON, true);
-    conn.addJsonEntity(method, vo);
+		conn.addJsonEntity(method, vo);
 		method.addHeader("Accept-Language", "en");
 		
 		HttpResponse response = conn.execute(method);
diff --git a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
index c01005efcb965df3032bb55492447af2b4b67b00..4a544ffd3e596a94aef8368028767d1065d393ea 100644
--- a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
+++ b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
@@ -78,6 +78,7 @@ import org.olat.restapi.support.vo.RepositoryEntryVOes;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatJerseyTestCase;
 import org.olat.user.restapi.UserVO;
+import org.olat.user.restapi.UserVOFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -87,6 +88,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	
 	private static final OLog log = Tracing.createLoggerFor(RepositoryEntriesTest.class);
+	private static final Roles ADMIN_ROLES = new Roles(true, false, false, false, false, false, false);
 
 	@Autowired
 	private BaseSecurity securityManager;
@@ -451,7 +453,7 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testGetOwners() throws IOException, URISyntaxException {
+	public void getOwners() throws IOException, URISyntaxException {
 		Identity owner1 = JunitTestHelper.createAndPersistIdentityAsAuthor("author-1-" + UUID.randomUUID().toString());
 		Identity owner2 = JunitTestHelper.createAndPersistIdentityAsAuthor("author-2-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
@@ -485,7 +487,7 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testAddOwners() throws IOException, URISyntaxException {
+	public void addOwner() throws IOException, URISyntaxException {
 		Identity owner = JunitTestHelper.createAndPersistIdentityAsAuthor("author-3-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
 		dbInstance.commitAndCloseSession();
@@ -513,7 +515,40 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testRemoveOwner() throws IOException, URISyntaxException {
+	public void addOwners() throws IOException, URISyntaxException {
+		Identity owner1 = JunitTestHelper.createAndPersistIdentityAsRndUser("author-3b-");
+		Identity owner2 = JunitTestHelper.createAndPersistIdentityAsRndUser("author-3c-");
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		dbInstance.commitAndCloseSession();
+
+		//add an owner
+		UserVO[] newOwners = new UserVO[2];
+		newOwners[0] = UserVOFactory.get(owner1);
+		newOwners[1] = UserVOFactory.get(owner2);
+		
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		URI request = UriBuilder.fromUri(getContextURI())
+				.path("repo").path("entries").path(re.getKey().toString()).path("owners").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, newOwners);
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+
+		conn.shutdown();
+		
+		//check
+		List<Identity> owners = repositoryService.getMembers(re, GroupRoles.owner.name());
+		Assert.assertNotNull(owners);
+		Assert.assertEquals(2, owners.size());
+		Assert.assertTrue(owners.contains(owner1));
+		Assert.assertTrue(owners.contains(owner2));
+	}
+	
+	@Test
+	public void removeOwner() throws IOException, URISyntaxException {
 		Identity owner = JunitTestHelper.createAndPersistIdentityAsAuthor("author-4-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
 		repositoryManager.addOwners(owner, new IdentitiesAddEvent(owner), re);
@@ -538,10 +573,8 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 		Assert.assertFalse(owners.contains(owner));
 	}
 	
-	private static final Roles ADMIN_ROLES = new Roles(true, false, false, false, false, false, false);
-	
 	@Test
-	public void testGetCoaches() throws IOException, URISyntaxException {
+	public void getCoaches() throws IOException, URISyntaxException {
 		Identity coach1 = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-1-" + UUID.randomUUID().toString());
 		Identity coach2 = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-2-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
@@ -575,7 +608,7 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testAddCoach() throws IOException, URISyntaxException {
+	public void addCoach() throws IOException, URISyntaxException {
 		Identity coach = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-3-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
 		dbInstance.commitAndCloseSession();
@@ -603,7 +636,40 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testRemoveCoach() throws IOException, URISyntaxException {
+	public void addCoaches() throws IOException, URISyntaxException {
+		Identity coach1 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-3b-");
+		Identity coach2 = JunitTestHelper.createAndPersistIdentityAsRndUser("coach-3c-");
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		dbInstance.commitAndCloseSession();
+
+		//add an owner
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+		
+		UserVO[] newCoaches = new UserVO[2];
+		newCoaches[0] = UserVOFactory.get(coach1);
+		newCoaches[1] = UserVOFactory.get(coach2);
+		
+		URI request = UriBuilder.fromUri(getContextURI())
+				.path("repo").path("entries").path(re.getKey().toString()).path("coaches").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, newCoaches);
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+
+		conn.shutdown();
+		
+		//check
+		List<Identity> coaches = repositoryService.getMembers(re, GroupRoles.coach.name());
+		Assert.assertNotNull(coaches);
+		Assert.assertEquals(2, coaches.size());
+		Assert.assertTrue(coaches.contains(coach1));
+		Assert.assertTrue(coaches.contains(coach2));
+	}
+	
+	@Test
+	public void removeCoach() throws IOException, URISyntaxException {
 		Identity coach = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-4-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
 		repositoryManager.addTutors(coach, ADMIN_ROLES, new IdentitiesAddEvent(coach), re, null);
@@ -629,7 +695,7 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testGetParticipants() throws IOException, URISyntaxException {
+	public void getParticipants() throws IOException, URISyntaxException {
 		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsAuthor("participant-1-" + UUID.randomUUID().toString());
 		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsAuthor("participant-2-" + UUID.randomUUID().toString());
 		Roles part1Roles = securityManager.getRoles(participant1);
@@ -663,7 +729,7 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	}
 	
 	@Test
-	public void testAddParticipants() throws IOException, URISyntaxException {
+	public void addParticipant() throws IOException, URISyntaxException {
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsAuthor("participant-3-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
 		dbInstance.commitAndCloseSession();
@@ -690,6 +756,41 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 		Assert.assertTrue(participants.contains(participant));
 	}
 	
+	@Test
+	public void addParticipants() throws IOException, URISyntaxException {
+		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("participant-3b-");
+		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("participant-3c-");
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		dbInstance.commitAndCloseSession();
+
+		//add an owner
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+
+		//add the 2 participants to the course
+		UserVO[] newParticipants = new UserVO[2];
+		newParticipants[0] = UserVOFactory.get(participant1);
+		newParticipants[1] = UserVOFactory.get(participant2);
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("repo/entries")
+				.path(re.getKey().toString()).path("participants").build();
+		
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, newParticipants);
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+
+		conn.shutdown();
+		
+		//check
+		List<Identity> participants = repositoryService.getMembers(re, GroupRoles.participant.name());
+		Assert.assertNotNull(participants);
+		Assert.assertEquals(2, participants.size());
+		Assert.assertTrue(participants.contains(participant1));
+		Assert.assertTrue(participants.contains(participant2));
+	}
+	
 	@Test
 	public void testRemoveParticipant() throws IOException, URISyntaxException {
 		Identity participant = JunitTestHelper.createAndPersistIdentityAsAuthor("participant-4-" + UUID.randomUUID().toString());