diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java b/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java
index 6dca311f822bd75660d682e12f30b32521c58bda..1660c8e249d53124301e3dcf054a9806362ed893 100644
--- a/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java
+++ b/src/main/java/org/olat/modules/curriculum/CurriculumRoles.java
@@ -19,6 +19,8 @@
  */
 package org.olat.modules.curriculum;
 
+import org.olat.core.util.StringHelper;
+
 /**
  * 
  * Initial date: 9 mai 2018<br>
@@ -28,5 +30,18 @@ package org.olat.modules.curriculum;
 public enum CurriculumRoles {
 	
 	supervisor,
-
+	owner, //same as GroupRoles
+	coach, //same as GroupRoles
+	participant; //same as GroupRoles
+	
+	public static final boolean isValueOf(String val) {
+		if(StringHelper.containsNonWhitespace(val)) {
+			for(CurriculumRoles role:values()) {
+				if(role.name().equals(val)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
 }
diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
index 2ea8768b7db82ee251d86859d442cb6861c3b757..754229852495cb305f32aa5ea307705d83524bb7 100644
--- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java
+++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
@@ -153,6 +153,15 @@ public interface CurriculumService {
 	 */
 	public List<CurriculumElementMember> getMembers(CurriculumElement element);
 	
+	/**
+	 * The list of members of the specified curriculum element with the specified role.
+	 * 
+	 * @param element The curriculum element
+	 * @param role The role
+	 * @return The list of memberships
+	 */
+	public List<Identity> getMembersIdentity(CurriculumElementRef element, CurriculumRoles role);
+	
 	/**
 	 * Add a member with the specified role to the curriculum element. The
 	 * inheritance mode of the membership is per default "none".
@@ -171,6 +180,15 @@ public interface CurriculumService {
 	 */
 	public void removeMember(CurriculumElement element, IdentityRef member);
 	
+	/**
+	 * Remove the membership of a user with the specified role.
+	 * 
+	 * @param element The curriculum element
+	 * @param member The identity which loose the membership
+	 * @param role The role
+	 */
+	public void removeMember(CurriculumElement element, IdentityRef member, CurriculumRoles role);
+	
 	/**
 	 * The all list of repository entries hold by the specified curriculum element.
 	 * 
@@ -179,6 +197,16 @@ public interface CurriculumService {
 	 */
 	public List<RepositoryEntry> getRepositoryEntries(CurriculumElementRef element);
 	
+	/**
+	 * Check if the repository entry is already in relation with the specified
+	 * curriculum element.
+	 * 
+	 * @param element The curriculum element
+	 * @param entry The repository entry
+	 * @return True if the repository entry and curriculum element share a group
+	 */
+	public boolean hasRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry);
+	
 	/**
 	 * This will add a relation between the curriculum element and the repository
 	 * entry and it will add the base group of the curriculum to the set of groups
@@ -191,6 +219,9 @@ public interface CurriculumService {
 	 */
 	public void addRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry, boolean master);
 	
+
+	public void removeRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry);
+	
 	
 	public List<CurriculumElementRepositoryEntryViews> getCurriculumElements(Identity identity, Roles roles, CurriculumRef curriculum);
 
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
index b255ac824284e69d19a762b785a4ff677ee6023f..180ef74fbb38de99d0cb481758bf9e753b08807c 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
@@ -30,6 +30,7 @@ import org.olat.core.commons.persistence.DB;
 import org.olat.core.commons.persistence.PersistenceHelper;
 import org.olat.core.id.Organisation;
 import org.olat.core.id.OrganisationRef;
+import org.olat.core.util.StringHelper;
 import org.olat.modules.curriculum.Curriculum;
 import org.olat.modules.curriculum.model.CurriculumImpl;
 import org.olat.modules.curriculum.model.CurriculumSearchParameters;
@@ -88,6 +89,25 @@ public class CurriculumDAO {
 			where = PersistenceHelper.appendAnd(sb, where);
 			sb.append(" cur.organisation.key in (:organisationKeys)");
 		}
+		
+		Long key = null;
+		String ref = null;
+		String fuzzyRef = null;
+		if(StringHelper.containsNonWhitespace(params.getSearchString())) {
+			ref = params.getSearchString();
+			fuzzyRef = PersistenceHelper.makeFuzzyQueryString(ref);
+			
+			where = PersistenceHelper.appendAnd(sb, where);
+			sb.append(" (cur.externalId=:ref or ");
+			PersistenceHelper.appendFuzzyLike(sb, "cur.displayName", "fuzzyRef", dbInstance.getDbVendor());
+			sb.append(" or ");
+			PersistenceHelper.appendFuzzyLike(sb, "cur.identifier", "fuzzyRef", dbInstance.getDbVendor());
+			if(StringHelper.isLong(ref)) {
+				key = Long.valueOf(ref);
+				sb.append(" or cur.key=:curriculumKey");
+			}
+			sb.append(")");	
+		}
 
 		TypedQuery<Curriculum> query = dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), Curriculum.class);
@@ -96,6 +116,15 @@ public class CurriculumDAO {
 					.stream().map(OrganisationRef::getKey).collect(Collectors.toList());
 			query.setParameter("organisationKeys", organisationKeys);
 		}
+		if(key != null) {
+			query.setParameter("curriculumKey", key);
+		}
+		if(ref != null) {
+			query.setParameter("ref", ref);
+		}
+		if(fuzzyRef != null) {
+			query.setParameter("fuzzyRef", fuzzyRef);
+		}
 		return query.getResultList();
 	}
 	
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
index 328ebc6fe7507e30cf247db885235602730dc7ae..1d57622bfa8adb85dec12c805a3f89161919adff 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
@@ -197,6 +197,7 @@ public class CurriculumElementDAO {
 		  .append(" inner join el.group baseGroup")
 		  .append(" inner join baseGroup.members membership")
 		  .append(" inner join membership.identity ident")
+		  .append(" inner join fetch ident.user identUser")
 		  .append(" where el.key=:elementKey");
 		List<Object[]> objects = dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), Object[].class)
@@ -216,6 +217,21 @@ public class CurriculumElementDAO {
 		return members;
 	}
 	
+	public List<Identity> getMembersIdentity(CurriculumElementRef element, String role) {
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select ident from curriculumelement el")
+		  .append(" inner join el.group baseGroup")
+		  .append(" inner join baseGroup.members membership")
+		  .append(" inner join membership.identity ident")
+		  .append(" inner join fetch ident.user identUser")
+		  .append(" where el.key=:elementKey and membership.role=:role");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Identity.class)
+				.setParameter("elementKey", element.getKey())
+				.setParameter("role", role)
+				.getResultList();
+	}
+	
 	private static class PathMaterializedPathLengthComparator implements Comparator<CurriculumElement> {
 		@Override
 		public int compare(CurriculumElement c1, CurriculumElement c2) {
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
index bad5f5dc2da52c9325cc8e43b0a573d92678b87c..b69f64fb796ea0e9cf79acda667e1d1f0884c28f 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
@@ -59,6 +59,25 @@ public class CurriculumRepositoryEntryRelationDAO {
 		return relation;
 	}
 	
+	public List<CurriculumRepositoryEntryRelation> getRelations(RepositoryEntryRef entry, CurriculumElementRef element) {
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select rel from repoentrytocurriculumelement as rel")
+		  .append(" where rel.entry.key=:repoKey and rel.curriculumElement.key=:elementKey");
+
+		return dbInstance.getCurrentEntityManager()
+			.createQuery(sb.toString(), CurriculumRepositoryEntryRelation.class)
+			.setParameter("repoKey", entry.getKey())
+			.setParameter("elementKey", element.getKey())
+			.getResultList();
+	}
+	
+	public void deleteRelation(RepositoryEntryRef entry, CurriculumElementRef element) {
+		List<CurriculumRepositoryEntryRelation> relations = getRelations(entry, element);
+		for(CurriculumRepositoryEntryRelation relation:relations) {
+			dbInstance.getCurrentEntityManager().remove(relation);
+		}
+	}
+	
 	public List<CurriculumElement> getCurriculumElements(RepositoryEntryRef entry) {
 		StringBuilder sb = new StringBuilder(256);
 		sb.append("select el from curriculumelement as el")
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
index 27a2854da3d7d227940ab3859b6f8d3b10c01972..7db12eb009bb52d1004975940fabb69cc1fdc67a 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
@@ -198,6 +198,11 @@ public class CurriculumServiceImpl implements CurriculumService {
 	public List<CurriculumElementMember> getMembers(CurriculumElement element) {
 		return curriculumElementDao.getMembers(element);
 	}
+	
+	@Override
+	public List<Identity> getMembersIdentity(CurriculumElementRef element, CurriculumRoles role) {
+		return curriculumElementDao.getMembersIdentity(element, role.name());
+	}
 
 	@Override
 	public void addMember(CurriculumElement element, Identity member, CurriculumRoles role) {
@@ -211,6 +216,11 @@ public class CurriculumServiceImpl implements CurriculumService {
 		groupDao.removeMembership(element.getGroup(), member);
 	}
 
+	@Override
+	public void removeMember(CurriculumElement element, IdentityRef member, CurriculumRoles role) {
+		groupDao.removeMembership(element.getGroup(), member, role.name());
+	}
+
 	@Override
 	public List<RepositoryEntry> getRepositoryEntries(CurriculumElementRef element) {
 		return curriculumRepositoryEntryRelationDao.getRepositoryEntries(element);
@@ -223,6 +233,17 @@ public class CurriculumServiceImpl implements CurriculumService {
 		curriculumRepositoryEntryRelationDao.createRelation(repoEntry, element, master);
 	}
 
+	@Override
+	public boolean hasRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry) {
+		return repositoryEntryRelationDao.hasRelation(element.getGroup(), entry);
+	}
+
+	@Override
+	public void removeRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry) {
+		repositoryEntryRelationDao.removeRelation(element.getGroup(), entry);
+		curriculumRepositoryEntryRelationDao.deleteRelation(entry, element);
+	}
+
 	@Override
 	public List<CurriculumElementRepositoryEntryViews> getCurriculumElements(Identity identity, Roles roles, CurriculumRef curriculum) {
 		if(curriculum == null) return Collections.emptyList();
diff --git a/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java b/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java
index 5f55323df0465b474cf8e313be40dad8a4a39ee1..4367f160272ee2d7c88c800acc26654dbe8f689b 100644
--- a/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java
+++ b/src/main/java/org/olat/modules/curriculum/model/CurriculumSearchParameters.java
@@ -32,6 +32,7 @@ import org.olat.core.id.OrganisationRef;
  */
 public class CurriculumSearchParameters {
 	
+	private String searchString;
 	private List<OrganisationRef> organisations;
 
 	public List<OrganisationRef> getOrganisations() {
@@ -44,7 +45,12 @@ public class CurriculumSearchParameters {
 	public void setOrganisations(List<OrganisationRef> organisations) {
 		this.organisations = organisations;
 	}
-	
-	
 
+	public String getSearchString() {
+		return searchString;
+	}
+
+	public void setSearchString(String searchString) {
+		this.searchString = searchString;
+	}
 }
diff --git a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementMemberVO.java b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementMemberVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..c81bb22ddf723c0675493a9a437e088200a6b491
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementMemberVO.java
@@ -0,0 +1,82 @@
+/**
+ * <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.curriculum.restapi;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.olat.modules.curriculum.model.CurriculumElementMember;
+
+/**
+ * 
+ * Initial date: 4 juin 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "curriculumElementMemberVO")
+public class CurriculumElementMemberVO {
+	
+	private Long identityKey;
+	private String role;
+	private String inheritanceMode;
+	
+	public CurriculumElementMemberVO() {
+		//
+	}
+	
+	public static final CurriculumElementMemberVO valueOf(CurriculumElementMember membership) {
+		CurriculumElementMemberVO vo = new CurriculumElementMemberVO();
+		vo.setIdentityKey(membership.getIdentity().getKey());
+		vo.setRole(membership.getRole());
+		if(membership.getInheritanceMode() != null) {
+			vo.setInheritanceMode(membership.getInheritanceMode().name());
+		}
+		return vo;
+	}
+
+	public Long getIdentityKey() {
+		return identityKey;
+	}
+
+	public void setIdentityKey(Long identityKey) {
+		this.identityKey = identityKey;
+	}
+
+	public String getRole() {
+		return role;
+	}
+
+	public void setRole(String role) {
+		this.role = role;
+	}
+
+	public String getInheritanceMode() {
+		return inheritanceMode;
+	}
+
+	public void setInheritanceMode(String inheritanceMode) {
+		this.inheritanceMode = inheritanceMode;
+	}
+	
+	
+
+}
diff --git a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java
index 4dbbfb1a342cb392b1818e4aa797324a645c03b0..1b3b1406a923401ecfa2fe50b473664882fe72a0 100644
--- a/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java
+++ b/src/main/java/org/olat/modules/curriculum/restapi/CurriculumElementsWebService.java
@@ -24,27 +24,38 @@ import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
+import org.olat.basesecurity.BaseSecurity;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
 import org.olat.modules.curriculum.Curriculum;
 import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumElementManagedFlag;
 import org.olat.modules.curriculum.CurriculumElementType;
+import org.olat.modules.curriculum.CurriculumRoles;
 import org.olat.modules.curriculum.CurriculumService;
+import org.olat.modules.curriculum.model.CurriculumElementMember;
 import org.olat.modules.curriculum.model.CurriculumElementRefImpl;
 import org.olat.modules.curriculum.model.CurriculumElementTypeRefImpl;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryService;
+import org.olat.user.restapi.UserVO;
+import org.olat.user.restapi.UserVOFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * The security checks are done by the CurriculumsWebService.
@@ -55,10 +66,20 @@ import org.olat.modules.curriculum.model.CurriculumElementTypeRefImpl;
  */
 public class CurriculumElementsWebService {
 	
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private BaseSecurity securityManager;
+	@Autowired
+	private CurriculumService curriculumService;
+	@Autowired
+	private RepositoryService repositoryService;
+	
 	private final Curriculum curriculum;
 	
 	public CurriculumElementsWebService(Curriculum curriculum) {
 		this.curriculum = curriculum;
+		CoreSpringFactory.autowireObject(this);
 	}
 	
 	/**
@@ -76,7 +97,6 @@ public class CurriculumElementsWebService {
 	@GET
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response getCurriculumElements() {
-		CurriculumService curriculumService = CoreSpringFactory.getImpl(CurriculumService.class);
 		List<CurriculumElement> elements = curriculumService.getCurriculumElements(curriculum);
 		List<CurriculumElementVO> voes = new ArrayList<>(elements.size());
 		for(CurriculumElement element:elements) {
@@ -101,7 +121,6 @@ public class CurriculumElementsWebService {
 	@Path("{curriculumElementKey}")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	public Response getCurriculumElement(@PathParam("curriculumElementKey") Long curriculumElementKey, @Context HttpServletRequest httpRequest) {
-		CurriculumService curriculumService = CoreSpringFactory.getImpl(CurriculumService.class);
 		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
 		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
@@ -190,8 +209,6 @@ public class CurriculumElementsWebService {
 	
 	
 	private CurriculumElement saveCurriculumElement(CurriculumElementVO curriculumElement) {
-		CurriculumService curriculumService = CoreSpringFactory.getImpl(CurriculumService.class);
-		
 		CurriculumElement elementToSave = null;
 		CurriculumElementType type = null;
 		if(curriculumElement.getCurriculumElementTypeKey() != null) {
@@ -229,15 +246,430 @@ public class CurriculumElementsWebService {
 		CurriculumElement savedElement = curriculumService.updateCurriculumElement(elementToSave);
 		if(move) {
 			curriculumService.moveCurriculumElement(savedElement, parentElement);
-			CoreSpringFactory.getImpl(DB.class).commit();
+			dbInstance.commit();
 			savedElement = curriculumService.getCurriculumElement(savedElement);
 		}
 		return savedElement;
 	}
 	
-	public void checkCurriculum(CurriculumElement element) {
+	private void checkCurriculum(CurriculumElement element) {
 		if(element.getCurriculum() != null && !element.getCurriculum().getKey().equals(curriculum.getKey())) {
 			throw new WebApplicationException(Response.serverError().status(Status.CONFLICT).build());
 		}
 	}
+	
+	/**
+	 * Add a relation between a repository entry and a curriculum element.
+	 * 
+	 * @response.representation.200.doc The relation was added
+	 * @response.representation.304.doc There is already a relation, nothing changed
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the repository entry was not found
+	 * @param curriculumElementKey The curriculum element
+	 * @param repositoryEntryKey The repository entry
+	 * @return Nothing
+	 */
+	@PUT
+	@Path("{curriculumElementKey}/entries/{repositoryEntryKey}")
+	public Response addRepositoryEntryToElement(@PathParam("curriculumElementKey") Long curriculumElementKey,
+			@PathParam("repositoryEntryKey") Long repositoryEntryKey) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		RepositoryEntry entry = repositoryService.loadByKey(repositoryEntryKey);
+		if(entry == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		if(!curriculumService.hasRepositoryEntry(curriculumElement, entry)) {
+			curriculumService.addRepositoryEntry(curriculumElement, entry, false);
+			return Response.ok().build();
+		}
+		return Response.ok().status(Status.NOT_MODIFIED).build();
+	}
+	
+	
+	/**
+	 * Remove a relation between a curriculum element and a repository entry.
+	 * 
+	 * @response.representation.200.doc The relation was successfully removed. 
+	 * @response.representation.304.doc There is no relation to remove
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the repository entry was not found
+	 * @param curriculumElementKey The curriculum element
+	 * @param repositoryEntryKey The repository entry
+	 * @return Nothing
+	 */
+	@DELETE
+	@Path("{curriculumElementKey}/entries/{repositoryEntryKey}")
+	public Response removeRepositoryEntryToElement(@PathParam("curriculumElementKey") Long curriculumElementKey,
+			@PathParam("repositoryEntryKey") Long repositoryEntryKey) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		RepositoryEntry entry = repositoryService.loadByKey(repositoryEntryKey);
+		if(entry == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		if(curriculumService.hasRepositoryEntry(curriculumElement, entry)) {
+			curriculumService.removeRepositoryEntry(curriculumElement, entry);
+			return Response.ok().build();
+		}
+		return Response.ok().status(Status.NOT_MODIFIED).build();
+	}
+	
+	/**
+	 * Get the memberships informations of the specified curriculum element.
+	 * 
+	 * @response.representation.200.qname {http://www.example.com}curriculumElementMemberVO
+	 * @response.representation.200.mediaType application/xml, application/json
+	 * @response.representation.200.doc The curriculum element membership
+	 * @response.representation.200.example {@link org.olat.modules.curriculum.restapi.Examples#SAMPLE_CURRICULUMELEMENTMEMBERVO}
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param httpRequest The HTTP request
+	 * @return The curriculum element
+	 */
+	@GET
+	@Path("{curriculumElementKey}/members")
+	public Response getMembers(@PathParam("curriculumElementKey") Long curriculumElementKey) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		
+		List<CurriculumElementMember> members = curriculumService.getMembers(curriculumElement);
+		List<CurriculumElementMemberVO> voList = new ArrayList<>(members.size());
+		for(CurriculumElementMember member:members) {
+			voList.add(CurriculumElementMemberVO.valueOf(member));
+		}
+		return Response.ok(voList.toArray(new CurriculumElementMemberVO[voList.size()])).build();
+	}
+	
+	/**
+	 * Get all members of the specified curriculum element. A query parameter can
+	 * specify the role of them.
+	 * 
+	 * @response.representation.200.qname {http://www.example.com}userVO
+	 * @response.representation.200.mediaType application/xml, application/json
+	 * @response.representation.200.doc The array of authors
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The course not found
+	 * @param httpRequest The HTTP request
+	 * @return It returns an array of <code>UserVO</code>
+	 */
+	@GET
+	@Path("{curriculumElementKey}/users")
+	public Response getUsers(@PathParam("curriculumElementKey") Long curriculumElementKey, @QueryParam("role") String role) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		if(role != null && !CurriculumRoles.isValueOf(role)) {
+			return Response.serverError().status(Status.CONFLICT).build();
+		}
+		
+		List<Identity> members = curriculumService.getMembersIdentity(curriculumElement, CurriculumRoles.valueOf(role));
+		List<UserVO> voList = new ArrayList<>(members.size());
+		for(Identity member:members) {
+			voList.add(UserVOFactory.get(member));
+		}
+		return Response.ok(voList.toArray(new UserVO[voList.size()])).build();
+	}
+	
+	/**
+	 * Add a membership to the specified curriculum element.
+	 * 
+	 * @response.representation.qname {http://www.example.com}curriculumElementMemberVO
+	 * @response.representation.mediaType application/xml, application/json
+	 * @response.representation.doc The curriculum element membership to persist
+	 * @response.representation.example {@link org.olat.modules.curriculum.restapi.Examples#SAMPLE_CURRICULUMELEMENTMEMBERVO}
+	 * @response.representation.200.doc The membership was persisted
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @response.representation.409.doc The role is not allowed
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param membership The membership informations
+	 * @return Nothing
+	 */
+	@PUT
+	@Path("{curriculumElementKey}/members")
+	public Response putMembers(@PathParam("curriculumElementKey") Long curriculumElementKey,
+			CurriculumElementMemberVO membership) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		Identity identity = securityManager.loadIdentityByKey(membership.getIdentityKey());
+		if(identity == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		String role = membership.getRole();
+		if(!CurriculumRoles.isValueOf(role)) {
+			return Response.serverError().status(Status.CONFLICT).build();
+		}
+		curriculumService.addMember(curriculumElement, identity, CurriculumRoles.valueOf(role));
+		return Response.ok().build();
+	}
+	
+	/**
+	 * Remove all memberships of the identity from the specified curriculum element.
+	 * 
+	 * @response.representation.200.doc The membership was removed
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param identityKey The member to remove
+	 * @return Nothing
+	 */
+	@DELETE
+	@Path("{curriculumElementKey}/members/{identityKey}")
+	public Response deleteMembers(@PathParam("curriculumElementKey") Long curriculumElementKey,
+			@PathParam("identityKey") Long identityKey) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		Identity identity = securityManager.loadIdentityByKey(identityKey);
+		if(identity == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		curriculumService.removeMember(curriculumElement, identity);
+		return Response.ok().build();
+	}
+	
+	/**
+	 * Get all participants of the specified curriculum element.
+	 * 
+	 * @response.representation.200.qname {http://www.example.com}userVO
+	 * @response.representation.200.mediaType application/xml, application/json
+	 * @response.representation.200.doc The array of participants
+	 * @response.representation.200.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes}
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element not found
+	 * @param httpRequest The HTTP request
+	 * @return It returns an array of <code>UserVO</code>
+	 */
+	@GET
+	@Path("{curriculumElementKey}/participants")
+	public Response getParticipants(@PathParam("curriculumElementKey") Long curriculumElementKey) {
+		return getMembers(curriculumElementKey, CurriculumRoles.participant);
+	}
+	
+	/**
+	 * Get all coaches of the specified curriculum element.
+	 * 
+	 * @response.representation.200.qname {http://www.example.com}userVO
+	 * @response.representation.200.mediaType application/xml, application/json
+	 * @response.representation.200.doc The array of coaches
+	 * @response.representation.200.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes}
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element not found
+	 * @param httpRequest The HTTP request
+	 * @return It returns an array of <code>UserVO</code>
+	 */
+	@GET
+	@Path("{curriculumElementKey}/coaches")
+	public Response getCoaches(@PathParam("curriculumElementKey") Long curriculumElementKey) {
+		return getMembers(curriculumElementKey, CurriculumRoles.coach);
+	}
+	
+	private Response getMembers(Long curriculumElementKey, CurriculumRoles role) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		List<Identity> members = curriculumService.getMembersIdentity(curriculumElement, role);
+		List<UserVO> voList = new ArrayList<>(members.size());
+		for(Identity member:members) {
+			voList.add(UserVOFactory.get(member));
+		}
+		return Response.ok(voList.toArray(new UserVO[voList.size()])).build();
+	}
+	
+	/**
+	 * Make the specified user a participant of the curriculum element.
+	 * 
+	 * @response.representation.200.doc The membership was added
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param identityKey The member to make a participant of
+	 * @return Nothing
+	 */
+	@PUT
+	@Path("{curriculumElementKey}/participants/{identityKey}")
+	public Response putParticipant(@PathParam("curriculumElementKey") Long curriculumElementKey, @PathParam("identityKey") Long identityKey) {
+		return putMember(curriculumElementKey, identityKey, CurriculumRoles.participant);
+	}
+	
+	/**
+	 * Make the specified user a coach of the curriculum element.
+	 * 
+	 * @response.representation.200.doc The membership was added
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param identityKey The member to make a coach of
+	 * @return Nothing
+	 */
+	@PUT
+	@Path("{curriculumElementKey}/coaches/{identityKey}")
+	public Response putCoach(@PathParam("curriculumElementKey") Long curriculumElementKey, @PathParam("identityKey") Long identityKey) {
+		return putMember(curriculumElementKey, identityKey, CurriculumRoles.coach);
+	}
+	
+	private Response putMember(Long curriculumElementKey, Long identityKey, CurriculumRoles role) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		Identity identity = securityManager.loadIdentityByKey(identityKey);
+		if(identity == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+
+		curriculumService.addMember(curriculumElement, identity, role);
+		return Response.ok().build();
+	}
+	
+	/**
+	 * Make the array of users participant of the specified curriculum element.
+	 * 
+	 * @response.representation.qname {http://www.example.com}userVO
+	 * @response.representation.mediaType application/xml, application/json
+	 * @response.representation.doc The curriculum element membership to persist
+	 * @response.representation.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes}
+	 * @response.representation.200.doc The memberships was persisted
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @response.representation.409.doc The role is not allowed
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param participants The future participants
+	 * @return Nothing
+	 */
+	@PUT
+	@Path("{curriculumElementKey}/participants")
+	public Response putParticipants(@PathParam("curriculumElementKey") Long curriculumElementKey, UserVO[] participants) {
+		return putMembers(curriculumElementKey, participants, CurriculumRoles.participant);
+	}
+	
+	/**
+	 * Make the array of users coach of the specified curriculum element.
+	 * 
+	 * @response.representation.qname {http://www.example.com}userVO
+	 * @response.representation.mediaType application/xml, application/json
+	 * @response.representation.doc The curriculum element membership to persist
+	 * @response.representation.example {@link org.olat.user.restapi.Examples#SAMPLE_USERVOes}
+	 * @response.representation.200.doc The memberships was persisted
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @response.representation.409.doc The role is not allowed
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param participants The future coaches
+	 * @return Nothing
+	 */
+	@PUT
+	@Path("{curriculumElementKey}/coaches")
+	public Response putCoach(@PathParam("curriculumElementKey") Long curriculumElementKey, UserVO[] coaches) {
+		return putMembers(curriculumElementKey, coaches, CurriculumRoles.coach);
+	}
+	
+	private Response putMembers(Long curriculumElementKey, UserVO[] members, CurriculumRoles role) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		
+		for(UserVO member:members) {
+			Identity identity = securityManager.loadIdentityByKey(member.getKey());
+			if(identity != null) {
+				curriculumService.addMember(curriculumElement, identity, role);
+			}
+		}
+		return Response.ok().build();
+	}
+	
+	/**
+	 * Remove the participant membership of the identity from the specified curriculum element.
+	 * 
+	 * @response.representation.200.doc The membership was removed
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param identityKey The member to remove
+	 * @return Nothing
+	 */
+	@DELETE
+	@Path("{curriculumElementKey}/participants/{identityKey}")
+	public Response deleteParticipant(@PathParam("curriculumElementKey") Long curriculumElementKey,
+			@PathParam("identityKey") Long identityKey) {
+		return deleteMember(curriculumElementKey, identityKey, CurriculumRoles.participant);
+	}
+	
+	/**
+	 * Remove the coach membership of the identity from the specified curriculum element.
+	 * 
+	 * @response.representation.200.doc The membership was removed
+	 * @response.representation.401.doc The roles of the authenticated user are not sufficient
+	 * @response.representation.404.doc The curriculum element or the identity was not found
+	 * @param curriculumElementKey The curriculum element primary key
+	 * @param identityKey The member to remove
+	 * @return Nothing
+	 */
+	@DELETE
+	@Path("{curriculumElementKey}/coaches/{identityKey}")
+	public Response deleteCoach(@PathParam("curriculumElementKey") Long curriculumElementKey,
+			@PathParam("identityKey") Long identityKey) {
+		return deleteMember(curriculumElementKey, identityKey, CurriculumRoles.coach);
+	}
+	
+	private Response deleteMember(Long curriculumElementKey, Long identityKey, CurriculumRoles role) {
+		CurriculumElement curriculumElement = curriculumService.getCurriculumElement(new CurriculumElementRefImpl(curriculumElementKey));
+		if(curriculumElement == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		if(!curriculumElement.getCurriculum().getKey().equals(curriculum.getKey())) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		Identity identity = securityManager.loadIdentityByKey(identityKey);
+		if(identity == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		
+		curriculumService.removeMember(curriculumElement, identity, role);
+		return Response.ok().build();
+	}
 }
diff --git a/src/main/java/org/olat/modules/curriculum/restapi/Examples.java b/src/main/java/org/olat/modules/curriculum/restapi/Examples.java
index 3be4ab6fed98ba5a9640b8a7a04f1d2f0059f644..4ff2e338ff34a87820a03dfef33fcc0e34a7a81d 100644
--- a/src/main/java/org/olat/modules/curriculum/restapi/Examples.java
+++ b/src/main/java/org/olat/modules/curriculum/restapi/Examples.java
@@ -35,6 +35,8 @@ public class Examples {
 	
 	public static final CurriculumElementTypeVO SAMPLE_CURRICULUMELEMENTTYPEVO = new CurriculumElementTypeVO();
 	
+	public static final CurriculumElementMemberVO SAMPLE_CURRICULUMELEMENTMEMBERVO = new CurriculumElementMemberVO();
+	
 	static {
 		SAMPLE_CURRICULUMVO.setKey(2l);
 		SAMPLE_CURRICULUMVO.setDisplayName("Dipl. engineer");
@@ -64,5 +66,9 @@ public class Examples {
 		SAMPLE_CURRICULUMELEMENTTYPEVO.setExternalId("CET-1001");
 		SAMPLE_CURRICULUMELEMENTTYPEVO.setDescription("This is the description of a type");
 		SAMPLE_CURRICULUMELEMENTTYPEVO.setManagedFlagsString("displayName");
+		
+		SAMPLE_CURRICULUMELEMENTMEMBERVO.setIdentityKey(111l);
+		SAMPLE_CURRICULUMELEMENTMEMBERVO.setInheritanceMode("none");
+		SAMPLE_CURRICULUMELEMENTMEMBERVO.setRole("participant");
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java
index 10c764bcf21342a938edaa6c42866e916b6f354b..1ce1db9398c1e23f48b03c8c70aef6c1cb404f0c 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumElementUserManagementController.java
@@ -108,8 +108,8 @@ public class CurriculumElementUserManagementController extends FormBasicControll
 		
 		membersManaged = CurriculumElementManagedFlag.isManaged(curriculumElement, CurriculumElementManagedFlag.members);
 
-		
 		initForm(ureq);
+		loadModel(true);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java
index 7f13273be280fe580b6723e3e37af9339c26104a..312937f8b86e99b7a8c3af1d5f7b84f33c51fa90 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java
@@ -83,7 +83,7 @@ public class CurriculumListController extends FormBasicController implements Act
 		toolsCol.setAlwaysVisible(true);
 		columnsModel.addFlexiColumnModel(toolsCol);
 		
-		tableModel = new CurriculumManagerDataModel(columnsModel);
+		tableModel = new CurriculumManagerDataModel(columnsModel, getLocale());
 		tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout);
 		tableEl.setCustomizeColumns(true);
 		tableEl.setEmtpyTableMessageKey("table.curriculum.empty");
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java
index ef489937689919242eaf27d795dc43462eda4e71..7acfbbfc96514b8fd1d60deccfc77abe77063258 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java
@@ -34,6 +34,7 @@ import org.olat.core.gui.components.form.flexible.impl.FormEvent;
 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.components.form.flexible.impl.elements.table.FlexiTableSearchEvent;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent;
 import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.components.link.LinkFactory;
@@ -88,7 +89,7 @@ public class CurriculumListManagerController extends FormBasicController impleme
 		this.secCallback = secCallback;
 		
 		initForm(ureq);
-		loadModel(true);
+		loadModel(null, true);
 	}
 	
 	@Override
@@ -111,15 +112,17 @@ public class CurriculumListManagerController extends FormBasicController impleme
 		toolsCol.setAlwaysVisible(true);
 		columnsModel.addFlexiColumnModel(toolsCol);
 		
-		tableModel = new CurriculumManagerDataModel(columnsModel);
+		tableModel = new CurriculumManagerDataModel(columnsModel, getLocale());
 		tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout);
 		tableEl.setCustomizeColumns(true);
 		tableEl.setEmtpyTableMessageKey("table.curriculum.empty");
 		tableEl.setAndLoadPersistedPreferences(ureq, "cur-curriculum-manage");
+		tableEl.setSearchEnabled(true);
 	}
 	
-	private void loadModel(boolean reset) {
+	private void loadModel(String searchString, boolean reset) {
 		CurriculumSearchParameters params = new CurriculumSearchParameters();
+		params.setSearchString(searchString);
 		List<Curriculum> curriculums = curriculumService.getCurriculums(params);
 		List<CurriculumRow> rows = curriculums.stream()
 				.map(this::forgeRow).collect(Collectors.toList());
@@ -149,13 +152,13 @@ public class CurriculumListManagerController extends FormBasicController impleme
 	protected void event(UserRequest ureq, Controller source, Event event) {
 		if(newCurriculumCtrl == source) {
 			if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
-				loadModel(true);
+				loadModel(tableEl.getQuickSearchString(), true);
 			}
 			cmc.deactivate();
 			cleanUp();
 		} else if(editCurriculumCtrl == source) {
 			if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
-				loadModel(false);
+				loadModel(tableEl.getQuickSearchString(), false);
 			}
 			cmc.deactivate();
 			cleanUp();
@@ -192,6 +195,8 @@ public class CurriculumListManagerController extends FormBasicController impleme
 					CurriculumRow row = tableModel.getObject(se.getIndex());
 					doSelectCurriculum(ureq, row);
 				}
+			} else if(event instanceof FlexiTableSearchEvent) {
+				doSearch((FlexiTableSearchEvent)event);
 			}
 		} else if (source instanceof FormLink) {
 			FormLink link = (FormLink)source;
@@ -203,6 +208,10 @@ public class CurriculumListManagerController extends FormBasicController impleme
 		super.formInnerEvent(ureq, source, event);
 	}
 	
+	private void doSearch(FlexiTableSearchEvent event) {
+		loadModel(event.getSearch(), true);
+	}
+	
 	private void doNewCurriculum(UserRequest ureq) {
 		if(newCurriculumCtrl != null) return;
 
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java
index 19596b80c10e2b33cfe0df4d239773da4b31d433..c00e3a680f808f484f465cd3d79c9ed0cd845354 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java
@@ -19,6 +19,9 @@
  */
 package org.olat.modules.curriculum.ui;
 
+import java.util.List;
+import java.util.Locale;
+
 import org.olat.core.commons.persistence.SortKey;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef;
@@ -34,13 +37,19 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFl
 public class CurriculumManagerDataModel extends DefaultFlexiTableDataModel<CurriculumRow>
 implements SortableFlexiTableDataModel<CurriculumRow> {
 	
-	public CurriculumManagerDataModel(FlexiTableColumnModel columnsModel) {
+	private final Locale locale;
+	
+	public CurriculumManagerDataModel(FlexiTableColumnModel columnsModel, Locale locale) {
 		super(columnsModel);
+		this.locale = locale;
 	}
 
 	@Override
-	public void sort(SortKey sortKey) {
-		//
+	public void sort(SortKey orderBy) {
+		if(orderBy != null) {
+			List<CurriculumRow> rows = new CurriculumManagerTableSort(orderBy, this, locale).sort();
+			super.setObjects(rows);
+		}
 	}
 	
 	@Override
@@ -62,7 +71,7 @@ implements SortableFlexiTableDataModel<CurriculumRow> {
 
 	@Override
 	public CurriculumManagerDataModel createCopyWithEmptyList() {
-		return new CurriculumManagerDataModel(getTableColumnModel());
+		return new CurriculumManagerDataModel(getTableColumnModel(), locale);
 	}
 	
 	public enum CurriculumCols implements FlexiSortableColumnDef {
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerTableSort.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerTableSort.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b5787ef89543eb85b6b393cc01264093889cda0
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerTableSort.java
@@ -0,0 +1,39 @@
+/**
+ * <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.curriculum.ui;
+
+import java.util.Locale;
+
+import org.olat.core.commons.persistence.SortKey;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate;
+
+/**
+ * 
+ * Initial date: 4 juin 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CurriculumManagerTableSort extends SortableFlexiTableModelDelegate<CurriculumRow> {
+	
+	public CurriculumManagerTableSort(SortKey orderBy, CurriculumManagerDataModel model, Locale locale) {
+		super(orderBy, model, locale);
+	}
+
+}
diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
index 4edcdb658076114804c08e19bd32cab926b3ceef..d49ff8f2865db9bb82c0d14bccfebcd2ae72e633 100644
--- a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
+++ b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
@@ -637,6 +637,22 @@ public class RepositoryEntryRelationDAO {
 			.getResultList();
 	}
 	
+	public boolean hasRelation(Group group, RepositoryEntryRef re) {
+		if(re == null || group == null) return false;
+		
+		String query = "select rel.key from repoentrytogroup as rel where rel.entry.key=:repoKey and rel.group.key=:groupKey";
+
+		List<Long> relations = dbInstance.getCurrentEntityManager()
+			.createQuery(query, Long.class)
+			.setParameter("repoKey", re.getKey())
+			.setParameter("groupKey", group.getKey())
+			.setFirstResult(0)
+			.setMaxResults(1)
+			.getResultList();
+		return relations != null && !relations.isEmpty() && relations.get(0) != null;
+	}
+	
+	
 	/**
 	 * Get the relation from a base group to the repository entries
 	 * 
diff --git a/src/main/java/org/olat/user/restapi/UserVO.java b/src/main/java/org/olat/user/restapi/UserVO.java
index b30341c23f8543ad9c76834ce15273491c8d1676..22dfcbb44d53804968ed405b2bba19e73ed4a73d 100644
--- a/src/main/java/org/olat/user/restapi/UserVO.java
+++ b/src/main/java/org/olat/user/restapi/UserVO.java
@@ -30,8 +30,6 @@ import javax.xml.bind.annotation.XmlRootElement;
 
 /**
  * 
- * Description:<br>
- * TODO: srosse Class Description for UserVO
  * 
  * <P>
  * Initial Date:  7 apr. 2010 <br>
@@ -52,7 +50,7 @@ public class UserVO {
 
 	@XmlElementWrapper(name="properties")
 	@XmlElement(name="property")
-	private List<UserPropertyVO> properties = new ArrayList<UserPropertyVO>();
+	private List<UserPropertyVO> properties = new ArrayList<>();
 
 	public UserVO() {
 		//make JAXB happy
diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java
index 0ca7a0812b192dc0b009f91f22f4fee691d6b703..816ba1b79c8ae14a1e92d2e1f6316bba9f604ee4 100644
--- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java
+++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumDAOTest.java
@@ -21,6 +21,7 @@ package org.olat.modules.curriculum.manager;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.UUID;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -111,4 +112,34 @@ public class CurriculumDAOTest extends OlatTestCase {
 		Assert.assertEquals(organisation, curriculums.get(0).getOrganisation());
 		Assert.assertNotNull(((CurriculumImpl)curriculums.get(0)).getGroup().getKey());
 	}
+	
+	@Test
+	public void search_searchString() {
+		String identifier = UUID.randomUUID().toString();
+		String displayName = UUID.randomUUID().toString();
+		Curriculum curriculum = curriculumDao.createAndPersist(identifier, displayName, "Short desc.", null);
+		dbInstance.commitAndCloseSession();
+		
+		// search something which doesn't exists
+		CurriculumSearchParameters params = new CurriculumSearchParameters();
+		params.setSearchString("AAAAAAAA");
+		List<Curriculum> curriculums = curriculumDao.search(params);
+		Assert.assertTrue(curriculums.isEmpty());
+		
+		// search by identifier
+		params.setSearchString(identifier);
+		List<Curriculum> curriculumById = curriculumDao.search(params);
+		Assert.assertEquals(1, curriculumById.size());
+		Assert.assertEquals(curriculum, curriculumById.get(0));
+		
+		// search by identifier
+		params.setSearchString(displayName.substring(0, 25).toUpperCase());
+		List<Curriculum> curriculumByName = curriculumDao.search(params);
+		Assert.assertTrue(curriculumByName.contains(curriculum));
+		
+		// search by primary key
+		params.setSearchString(curriculum.getKey().toString());
+		List<Curriculum> curriculumByKey = curriculumDao.search(params);
+		Assert.assertTrue(curriculumByKey.contains(curriculum));
+	}
 }
diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java
index 42300f605bf6b89a740d53a609062d0d33ca2e1b..39ba217d771d6e05f423c1d1079595c91d20c351 100644
--- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java
+++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumElementDAOTest.java
@@ -235,4 +235,18 @@ public class CurriculumElementDAOTest extends OlatTestCase {
 		Assert.assertEquals(supervisor, member.getIdentity());
 		Assert.assertEquals(CurriculumRoles.supervisor.name(), member.getRole());
 	}
+	
+	@Test
+	public void getMembersIdentity() {
+		Identity supervisor = JunitTestHelper.createAndPersistIdentityAsRndUser("cur-supervisor-1");
+		Curriculum curriculum = curriculumService.createCurriculum("cur-for-el-4", "Curriculum for element", "Curriculum", null);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-4", "4. Element", null, null, null, null, curriculum);
+		curriculumService.addMember(element, supervisor, CurriculumRoles.supervisor);
+		dbInstance.commitAndCloseSession();
+		
+		List<Identity> members = curriculumElementDao.getMembersIdentity(element, CurriculumRoles.supervisor.name());
+		Assert.assertNotNull(members);
+		Assert.assertEquals(1, members.size());
+		Assert.assertEquals(supervisor, members.get(0));
+	}
 }
diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
index 2bbd97a47b5653eef9c26a8576bb63b207cbac16..e1355c80ddcbf1247a707d4734f2156338abe9db 100644
--- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
+++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
@@ -84,7 +84,6 @@ public class CurriculumRepositoryEntryRelationDAOTest extends OlatTestCase {
 		Assert.assertEquals(entry, entries.get(0));
 	}
 	
-	
 	@Test
 	public void getCurriculumElements() {
 		Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-2", "Curriculum for relation", "Curriculum", null);
@@ -101,5 +100,43 @@ public class CurriculumRepositoryEntryRelationDAOTest extends OlatTestCase {
 		Assert.assertEquals(element, elements.get(0));
 	}
 	
-
+	@Test
+	public void getRelations() {
+		Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-3", "Curriculum for relation", "Curriculum", null);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-for-rel", "Element for relation", null, null, null, null, curriculum);
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("cur-el-re-auth");
+		RepositoryEntry entry = JunitTestHelper.createRandomRepositoryEntry(author);
+		dbInstance.commit();
+		curriculumService.addRepositoryEntry(element, entry, false);
+		dbInstance.commitAndCloseSession();
+		
+		List<CurriculumRepositoryEntryRelation> relations = curriculumRepositoryEntryRelationDao.getRelations(entry, element);
+		Assert.assertNotNull(relations);
+		Assert.assertEquals(1, relations.size());
+		Assert.assertEquals(element, relations.get(0).getCurriculumElement());
+		Assert.assertEquals(entry, relations.get(0).getEntry());
+	}
+	
+	@Test
+	public void deleteRelations() {
+		Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-4", "Curriculum for relation", "Curriculum", null);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-for-rel", "Element for relation", null, null, null, null, curriculum);
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("cur-el-re-auth");
+		RepositoryEntry entry = JunitTestHelper.createRandomRepositoryEntry(author);
+		dbInstance.commit();
+		curriculumService.addRepositoryEntry(element, entry, false);
+		dbInstance.commitAndCloseSession();
+		
+		// check if the relation is really there.
+		List<CurriculumRepositoryEntryRelation> relations = curriculumRepositoryEntryRelationDao.getRelations(entry, element);
+		Assert.assertEquals(1, relations.size());
+		
+		// delete the relations
+		curriculumRepositoryEntryRelationDao.deleteRelation(entry, element);
+		dbInstance.commitAndCloseSession();
+		
+		// check that there isn't a relation left
+		List<CurriculumRepositoryEntryRelation> deletedRelations = curriculumRepositoryEntryRelationDao.getRelations(entry, element);
+		Assert.assertTrue(deletedRelations.isEmpty());
+	}
 }
diff --git a/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java b/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java
index f72ddc06f9025fc4818e69edbfdf385eb506aae8..9076f8868446350e978f55e7736d2b77fdb5c0d5 100644
--- a/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java
+++ b/src/test/java/org/olat/repository/manager/RepositoryEntryRelationDAOTest.java
@@ -425,8 +425,8 @@ public class RepositoryEntryRelationDAOTest extends OlatTestCase {
 	}
 	
 	@Test
-	public void getRelations() {
-		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("re-member-lc-" + UUID.randomUUID().toString());
+	public void getRelations_group() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("re-member-lc-" );
 		RepositoryEntry re1 = JunitTestHelper.createAndPersistRepositoryEntry();
 		RepositoryEntry re2 = JunitTestHelper.createAndPersistRepositoryEntry();
 
@@ -444,6 +444,40 @@ public class RepositoryEntryRelationDAOTest extends OlatTestCase {
 		Assert.assertTrue(relations.get(1).getEntry().equals(re1) || relations.get(1).getEntry().equals(re2));
 	}
 	
+	@Test
+	public void getRelations_repositoryEntry() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("re-member-lc-");
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+
+		BusinessGroup group = businessGroupService.createBusinessGroup(null, "get relations", "tg", null, null, false, false, re);
+	    businessGroupRelationDao.addRole(id, group, GroupRoles.coach.name());
+	    dbInstance.commitAndCloseSession();
+	    
+	    //get the relations from the business group's base group to the repository entry
+	    List<RepositoryEntryToGroupRelation> relations = repositoryEntryRelationDao.getRelations(re);
+	    Assert.assertNotNull(relations);
+	    Assert.assertEquals(3, relations.size());
+		Assert.assertTrue(relations.get(0).getEntry().equals(re));
+	}
+	
+	@Test
+	public void hasRelation() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("re-member-lc-");
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry reMarker = JunitTestHelper.createAndPersistRepositoryEntry();
+
+		BusinessGroup group = businessGroupService.createBusinessGroup(null, "get relations", "tg", null, null, false, false, re);
+	    businessGroupRelationDao.addRole(id, group, GroupRoles.coach.name());
+	    dbInstance.commitAndCloseSession();
+	    
+	    // The repository entry has a relation with the business group
+	    boolean hasRelation = repositoryEntryRelationDao.hasRelation(group.getBaseGroup(), re);
+		Assert.assertTrue(hasRelation);
+	    // The marker repository entry doesn't have a relation with the business group
+	    boolean hasNotRelation = repositoryEntryRelationDao.hasRelation(group.getBaseGroup(), reMarker);
+		Assert.assertFalse(hasNotRelation);
+	}
+	
 	@Test
 	public void getIdentitiesWithRole() {
 		Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("id-role-1-");
diff --git a/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java b/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java
index ada2e6ef5a0286282b13a91185f23898e1eb5494..daf0b1b016d1199183bc02d7f219ad77f31d057f 100644
--- a/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java
+++ b/src/test/java/org/olat/restapi/CurriculumElementsWebServiceTest.java
@@ -30,7 +30,9 @@ import java.util.List;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriBuilder;
 
+import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpPut;
@@ -42,15 +44,23 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.olat.basesecurity.OrganisationService;
 import org.olat.core.commons.persistence.DB;
+import org.olat.core.id.Identity;
 import org.olat.core.id.Organisation;
 import org.olat.modules.curriculum.Curriculum;
 import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumElementManagedFlag;
 import org.olat.modules.curriculum.CurriculumElementType;
+import org.olat.modules.curriculum.CurriculumRoles;
 import org.olat.modules.curriculum.CurriculumService;
+import org.olat.modules.curriculum.model.CurriculumElementMember;
 import org.olat.modules.curriculum.model.CurriculumElementRefImpl;
+import org.olat.modules.curriculum.restapi.CurriculumElementMemberVO;
 import org.olat.modules.curriculum.restapi.CurriculumElementVO;
+import org.olat.repository.RepositoryEntry;
+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;
 
 /**
@@ -84,8 +94,7 @@ public class CurriculumElementsWebServiceTest extends OlatJerseyTestCase {
 		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
 		HttpResponse response = conn.execute(method);
 		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
-		InputStream body = response.getEntity().getContent();
-		List<CurriculumElementVO> elementVoes = parseCurriculumElementArray(body);
+		List<CurriculumElementVO> elementVoes = parseCurriculumElementArray(response.getEntity());
 		Assert.assertNotNull(elementVoes);
 		Assert.assertEquals(2, elementVoes.size());
 		
@@ -345,14 +354,449 @@ public class CurriculumElementsWebServiceTest extends OlatJerseyTestCase {
 	}
 	
 	
-	protected List<CurriculumElementVO> parseCurriculumElementArray(InputStream body) {
-		try {
+	@Test
+	public void addRepositoryEntryToCurriculumElement()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 4", "REST-p-4-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-11", "Element 11", null, null, null, null, curriculum);
+		dbInstance.commitAndCloseSession();
+
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndAuthor("rest-auth-1");
+		RepositoryEntry course = JunitTestHelper.createRandomRepositoryEntry(author);
+		dbInstance.commitAndCloseSession();
+
+		// add the relation
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("entries").path(course.getKey().toString()).build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<RepositoryEntry> entries = curriculumService.getRepositoryEntries(element);
+		Assert.assertNotNull(entries);
+		Assert.assertEquals(1, entries.size());
+		Assert.assertEquals(course, entries.get(0));
+	}
+	
+	@Test
+	public void removeRepositoryEntryFromCurriculumElement()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum);
+		dbInstance.commit();
+
+		Identity author = JunitTestHelper.createAndPersistIdentityAsRndAuthor("rest-auth-2");
+		RepositoryEntry entry = JunitTestHelper.createRandomRepositoryEntry(author);
+		dbInstance.commit();
+		
+		curriculumService.addRepositoryEntry(element, entry, false);
+		dbInstance.commitAndCloseSession();
+		
+		List<RepositoryEntry> entries = curriculumService.getRepositoryEntries(element);
+		Assert.assertEquals(1, entries.size());
+		
+
+		//try to delete the relation
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("entries").path(entry.getKey().toString()).build();
+		HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<RepositoryEntry> deletedRelations = curriculumService.getRepositoryEntries(element);
+		Assert.assertNotNull(deletedRelations);
+		Assert.assertTrue(deletedRelations.isEmpty());
+	}
+	
+	@Test
+	public void getMemberships()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-1");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		curriculumService.addMember(element, member, CurriculumRoles.participant);
+		dbInstance.commitAndCloseSession();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("members").build();
+		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		List<CurriculumElementMemberVO> memberVoes = parseCurriculumElementMemberArray(response.getEntity());
+		
+		Assert.assertNotNull(memberVoes);
+		Assert.assertEquals(1, memberVoes.size());
+		Assert.assertEquals(member.getKey(), memberVoes.get(0).getIdentityKey());
+		Assert.assertEquals("participant", memberVoes.get(0).getRole());
+	}
+	
+	@Test
+	public void getUsers()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-6");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 8", "REST-p-8-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-14", "Element 14", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		curriculumService.addMember(element, member, CurriculumRoles.participant);
+		dbInstance.commitAndCloseSession();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("users").queryParam("role", "participant").build();
+		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		List<UserVO> memberVoes = parseUserArray(response.getEntity());
+		
+		Assert.assertNotNull(memberVoes);
+		Assert.assertEquals(1, memberVoes.size());
+		Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey());
+	}
+	
+	@Test
+	public void getParticipants()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-7");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 9", "REST-p-9-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-15", "Element 15", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		curriculumService.addMember(element, member, CurriculumRoles.participant);
+		dbInstance.commitAndCloseSession();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("participants").build();
+		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		List<UserVO> memberVoes = parseUserArray(response.getEntity());
+		
+		Assert.assertNotNull(memberVoes);
+		Assert.assertEquals(1, memberVoes.size());
+		Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey());
+	}
+	
+	@Test
+	public void getCoaches()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-10");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 10", "REST-p-10-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-16", "Element 16", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		curriculumService.addMember(element, member, CurriculumRoles.coach);
+		dbInstance.commitAndCloseSession();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("coaches").build();
+		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		List<UserVO> memberVoes = parseUserArray(response.getEntity());
+		
+		Assert.assertNotNull(memberVoes);
+		Assert.assertEquals(1, memberVoes.size());
+		Assert.assertEquals(member.getKey(), memberVoes.get(0).getKey());
+	}
+	
+	@Test
+	public void addMembership()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-1");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		CurriculumElementMemberVO membershipVo = new CurriculumElementMemberVO();
+		membershipVo.setIdentityKey(member.getKey());
+		membershipVo.setRole("participant");
+		membershipVo.setInheritanceMode("none");
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("members").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, membershipVo);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<CurriculumElementMember> members = curriculumService.getMembers(element);
+		Assert.assertNotNull(members);
+		Assert.assertEquals(1, members.size());
+		Assert.assertEquals(member, members.get(0).getIdentity());
+		Assert.assertEquals("participant", members.get(0).getRole());
+	}
+	
+	@Test
+	public void addParticipant()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-11");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 11", "REST-p-11-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-17", "Element 17", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("participants").path(participant.getKey().toString()).build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<Identity> participants = curriculumService.getMembersIdentity(element, CurriculumRoles.participant);
+		Assert.assertNotNull(participants);
+		Assert.assertEquals(1, participants.size());
+		Assert.assertEquals(participant, participants.get(0));
+	}
+	
+	@Test
+	public void addCoach()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-12");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 12", "REST-p-12-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-18", "Element 18", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("coaches").path(coach.getKey().toString()).build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<Identity> coaches = curriculumService.getMembersIdentity(element, CurriculumRoles.coach);
+		Assert.assertNotNull(coaches);
+		Assert.assertEquals(1, coaches.size());
+		Assert.assertEquals(coach, coaches.get(0));
+	}
+	
+	@Test
+	public void addParticipants()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-13");
+		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-14");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 13", "REST-p-13-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-18", "Element 18", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		UserVO[] participants = new UserVO[] {
+			UserVOFactory.get(participant1),
+			UserVOFactory.get(participant2)
+		};
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("participants").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, participants);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<Identity> participantList = curriculumService.getMembersIdentity(element, CurriculumRoles.participant);
+		Assert.assertNotNull(participantList);
+		Assert.assertEquals(2, participantList.size());
+	}
+	
+	@Test
+	public void addCoaches()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity coach1 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-15");
+		Identity coach2 = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-16");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 16", "REST-p-16-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-20", "Element 20", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		UserVO[] coaches = new UserVO[] {
+			UserVOFactory.get(coach1),
+			UserVOFactory.get(coach2)
+		};
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("coaches").build();
+		HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true);
+		conn.addJsonEntity(method, coaches);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<Identity> coachList = curriculumService.getMembersIdentity(element, CurriculumRoles.coach);
+		Assert.assertNotNull(coachList);
+		Assert.assertEquals(2, coachList.size());
+	}
+	
+	@Test
+	public void removeMembership()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity member = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-1");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 5", "REST-p-5-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-12", "Element 12", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		curriculumService.addMember(element, member, CurriculumRoles.participant);
+		dbInstance.commitAndCloseSession();
+
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("members").path(member.getKey().toString()).build();
+		HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<CurriculumElementMember> members = curriculumService.getMembers(element);
+		Assert.assertNotNull(members);
+		Assert.assertTrue(members.isEmpty());
+	}
+	
+	@Test
+	public void removeParticipant()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-21");
+		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-22");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 21", "REST-p-21-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-21", "Element 21", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		curriculumService.addMember(element, participant, CurriculumRoles.participant);
+		curriculumService.addMember(element, coach, CurriculumRoles.coach);
+		dbInstance.commitAndCloseSession();
+
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("participants").path(participant.getKey().toString()).build();
+		HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<Identity> participants = curriculumService.getMembersIdentity(element, CurriculumRoles.participant);
+		Assert.assertTrue(participants.isEmpty());
+		List<Identity> coaches = curriculumService.getMembersIdentity(element, CurriculumRoles.coach);
+		Assert.assertEquals(1, coaches.size());
+	}
+	
+	@Test
+	public void removeCoach()
+	throws IOException, URISyntaxException {
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-23");
+		Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("element-member-24");
+		Organisation organisation = organisationService.createOrganisation("REST Parent Organisation 24", "REST-p-24-organisation", "", null, null);
+		Curriculum curriculum = curriculumService.createCurriculum("REST-Curriculum-elements", "REST Curriculum", "A curriculum accessible by REST API for elemets", organisation);
+		CurriculumElement element = curriculumService.createCurriculumElement("Element-24", "Element 24", null, null, null, null, curriculum);
+		dbInstance.commit();
+		
+		curriculumService.addMember(element, participant, CurriculumRoles.participant);
+		curriculumService.addMember(element, coach, CurriculumRoles.coach);
+		dbInstance.commitAndCloseSession();
+
+		URI request = UriBuilder.fromUri(getContextURI()).path("curriculum").path(curriculum.getKey().toString())
+				.path("elements").path(element.getKey().toString()).path("coaches").path(coach.getKey().toString()).build();
+		HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_JSON);
+		
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		List<Identity> coaches = curriculumService.getMembersIdentity(element, CurriculumRoles.coach);
+		Assert.assertTrue(coaches.isEmpty());
+		List<Identity> participants = curriculumService.getMembersIdentity(element, CurriculumRoles.participant);
+		Assert.assertEquals(1, participants.size());
+	}
+	
+	protected List<UserVO> parseUserArray(HttpEntity body) {
+		try(InputStream in = body.getContent()) {
 			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
-			return mapper.readValue(body, new TypeReference<List<CurriculumElementVO>>(){/* */});
+			return mapper.readValue(in, new TypeReference<List<UserVO>>(){/* */});
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	protected List<CurriculumElementVO> parseCurriculumElementArray(HttpEntity body) {
+		try(InputStream in = body.getContent()) {
+			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
+			return mapper.readValue(in, new TypeReference<List<CurriculumElementVO>>(){/* */});
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	protected List<CurriculumElementMemberVO> parseCurriculumElementMemberArray(HttpEntity body) {
+		try(InputStream in = body.getContent()) {
+			ObjectMapper mapper = new ObjectMapper(jsonFactory); 
+			return mapper.readValue(in, new TypeReference<List<CurriculumElementMemberVO>>(){/* */});
 		} catch (Exception e) {
 			e.printStackTrace();
 			return null;
 		}
 	}
-
 }