diff --git a/src/main/java/org/olat/basesecurity/GroupMembershipInheritance.java b/src/main/java/org/olat/basesecurity/GroupMembershipInheritance.java
index c00cfa8e065bd6f96e463271542b02e8a2998182..469a4ad7f590198c4e46b38303d5892446e5758f 100644
--- a/src/main/java/org/olat/basesecurity/GroupMembershipInheritance.java
+++ b/src/main/java/org/olat/basesecurity/GroupMembershipInheritance.java
@@ -19,6 +19,8 @@
  */
 package org.olat.basesecurity;
 
+import org.olat.core.util.StringHelper;
+
 /**
  * 
  * Initial date: 3 mai 2018<br>
@@ -29,6 +31,16 @@ public enum GroupMembershipInheritance {
 	
 	none,
 	root,//
-	inherited
-
+	inherited;
+	
+	public static boolean isValueOf(String val) {
+		if(StringHelper.containsNonWhitespace(val)) {
+			for(GroupMembershipInheritance value:values()) {
+				if(value.name().equals(val)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
 }
diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumRepositoryEntryRelation.java b/src/main/java/org/olat/modules/curriculum/CurriculumRepositoryEntryRelation.java
deleted file mode 100644
index c57779bed167432b8f29b3b635b9c15148de9118..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/curriculum/CurriculumRepositoryEntryRelation.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * <a href="http://www.openolat.org">
- * OpenOLAT - Online Learning and Training</a><br>
- * <p>
- * Licensed under the Apache License, Version 2.0 (the "License"); <br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at the
- * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
- * <p>
- * Unless required by applicable law or agreed to in writing,<br>
- * software distributed under the License is distributed on an "AS IS" BASIS, <br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
- * See the License for the specific language governing permissions and <br>
- * limitations under the License.
- * <p>
- * Initial code contributed and copyrighted by<br>
- * frentix GmbH, http://www.frentix.com
- * <p>
- */
-package org.olat.modules.curriculum;
-
-import org.olat.core.id.CreateInfo;
-import org.olat.core.id.ModifiedInfo;
-import org.olat.repository.RepositoryEntry;
-
-/**
- * 
- * Initial date: 9 mai 2018<br>
- * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
- *
- */
-public interface CurriculumRepositoryEntryRelation extends CreateInfo, ModifiedInfo {
-	
-	public Long getKey();
-	
-	public CurriculumElement getCurriculumElement();
-	
-	public RepositoryEntry getEntry();
-	
-	public boolean isMaster();
-
-}
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 b69f64fb796ea0e9cf79acda667e1d1f0884c28f..84df519633fb68d8c5f32be5302e6e3d2bc498ca 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
@@ -20,7 +20,6 @@
 package org.olat.modules.curriculum.manager;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -29,8 +28,6 @@ import org.olat.core.commons.persistence.DB;
 import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumElementRef;
 import org.olat.modules.curriculum.CurriculumRef;
-import org.olat.modules.curriculum.CurriculumRepositoryEntryRelation;
-import org.olat.modules.curriculum.model.CurriculumRepositoryEntryRelationImpl;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -48,36 +45,6 @@ public class CurriculumRepositoryEntryRelationDAO {
 	@Autowired
 	private DB dbInstance;
 	
-	public CurriculumRepositoryEntryRelation createRelation(RepositoryEntry entry, CurriculumElement element, boolean master) {
-		CurriculumRepositoryEntryRelationImpl relation = new CurriculumRepositoryEntryRelationImpl();
-		relation.setCreationDate(new Date());
-		relation.setLastModified(relation.getCreationDate());
-		relation.setCurriculumElement(element);
-		relation.setEntry(entry);
-		relation.setMaster(master);
-		dbInstance.getCurrentEntityManager().persist(relation);
-		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 f1a2918299b4bb199b4ff09356479c3160796668..31809f0a67870ddef212f26c91acaf8016c17818 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
@@ -315,7 +315,6 @@ public class CurriculumServiceImpl implements CurriculumService {
 	public void addRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry, boolean master) {
 		RepositoryEntry repoEntry = repositoryEntryDao.loadByKey(entry.getKey());
 		repositoryEntryRelationDao.createRelation(element.getGroup(), repoEntry);
-		curriculumRepositoryEntryRelationDao.createRelation(repoEntry, element, master);
 	}
 
 	@Override
@@ -326,7 +325,6 @@ public class CurriculumServiceImpl implements CurriculumService {
 	@Override
 	public void removeRepositoryEntry(CurriculumElement element, RepositoryEntryRef entry) {
 		repositoryEntryRelationDao.removeRelation(element.getGroup(), entry);
-		curriculumRepositoryEntryRelationDao.deleteRelation(entry, element);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/curriculum/model/CurriculumRepositoryEntryRelationImpl.java b/src/main/java/org/olat/modules/curriculum/model/CurriculumRepositoryEntryRelationImpl.java
deleted file mode 100644
index 271482c1b89c83716d29f967a4aeb39fe4a86b09..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/modules/curriculum/model/CurriculumRepositoryEntryRelationImpl.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * <a href="http://www.openolat.org">
- * OpenOLAT - Online Learning and Training</a><br>
- * <p>
- * Licensed under the Apache License, Version 2.0 (the "License"); <br>
- * you may not use this file except in compliance with the License.<br>
- * You may obtain a copy of the License at the
- * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
- * <p>
- * Unless required by applicable law or agreed to in writing,<br>
- * software distributed under the License is distributed on an "AS IS" BASIS, <br>
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
- * See the License for the specific language governing permissions and <br>
- * limitations under the License.
- * <p>
- * Initial code contributed and copyrighted by<br>
- * frentix GmbH, http://www.frentix.com
- * <p>
- */
-package org.olat.modules.curriculum.model;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.olat.core.id.Persistable;
-import org.olat.modules.curriculum.CurriculumElement;
-import org.olat.modules.curriculum.CurriculumRepositoryEntryRelation;
-import org.olat.repository.RepositoryEntry;
-
-/**
- * 
- * Initial date: 9 mai 2018<br>
- * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
- *
- */
-@Entity(name="repoentrytocurriculumelement")
-@Table(name="o_re_to_curriculum_element")
-public class CurriculumRepositoryEntryRelationImpl implements CurriculumRepositoryEntryRelation, Persistable {
-
-	private static final long serialVersionUID = -4889700699342402333L;
-
-	@Id
-	@GeneratedValue(strategy = GenerationType.IDENTITY)
-	@Column(name="id", nullable=false, unique=true, insertable=true, updatable=false)
-	private Long key;
-	
-	@Temporal(TemporalType.TIMESTAMP)
-	@Column(name="creationdate", nullable=false, insertable=true, updatable=false)
-	private Date creationDate;
-	@Temporal(TemporalType.TIMESTAMP)
-	@Column(name="lastmodified", nullable=false, insertable=true, updatable=true)
-	private Date lastModified;
-	
-    @Column(name="c_master", nullable=true, insertable=true, updatable=false)
-	private boolean master;
-	
-	@ManyToOne(targetEntity=RepositoryEntry.class,fetch=FetchType.LAZY,optional=true)
-	@JoinColumn(name="fk_entry", nullable=true, insertable=true, updatable=true)
-    private RepositoryEntry entry;
-
-	@ManyToOne(targetEntity=CurriculumElementImpl.class,fetch=FetchType.LAZY,optional=true)
-	@JoinColumn(name="fk_curriculum_element", nullable=true, insertable=true, updatable=false)
-    private CurriculumElement curriculumElement;
-
-	@Override
-	public Long getKey() {
-		return key;
-	}
-
-	public void setKey(Long key) {
-		this.key = key;
-	}
-
-	@Override
-	public Date getCreationDate() {
-		return creationDate;
-	}
-	
-	public void setCreationDate(Date creationDate) {
-		this.creationDate = creationDate;
-	}
-
-	@Override
-	public Date getLastModified() {
-		return lastModified;
-	}
-
-	@Override
-	public void setLastModified(Date lastModified) {
-		this.lastModified = lastModified;
-	}
-
-	@Override
-	public boolean isMaster() {
-		return master;
-	}
-
-	public void setMaster(boolean master) {
-		this.master = master;
-	}
-
-	@Override
-	public RepositoryEntry getEntry() {
-		return entry;
-	}
-
-	public void setEntry(RepositoryEntry entry) {
-		this.entry = entry;
-	}
-
-	@Override
-	public CurriculumElement getCurriculumElement() {
-		return curriculumElement;
-	}
-
-	public void setCurriculumElement(CurriculumElement curriculumElement) {
-		this.curriculumElement = curriculumElement;
-	}
-
-	@Override
-	public int hashCode() {
-		return getKey() == null ? 391598261 : getKey().hashCode();
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if(this == obj) {
-			return true;
-		}
-		if(obj instanceof CurriculumRepositoryEntryRelationImpl) {
-			CurriculumRepositoryEntryRelationImpl rel = (CurriculumRepositoryEntryRelationImpl)obj;
-			return getKey() != null && getKey().equals(rel.getKey());
-		}
-		
-		return false;
-	}
-
-	@Override
-	public boolean equalsByPersistableKey(Persistable persistable) {
-		return equals(persistable);
-	}
-}
diff --git a/src/main/java/org/olat/modules/lecture/LectureService.java b/src/main/java/org/olat/modules/lecture/LectureService.java
index be5bfa64ad871dc64ed06c74a8598e614288437f..8af6eaab96af348c20eb463cf3314af3beed8667 100644
--- a/src/main/java/org/olat/modules/lecture/LectureService.java
+++ b/src/main/java/org/olat/modules/lecture/LectureService.java
@@ -180,6 +180,8 @@ public interface LectureService {
 	 */
 	public LectureBlock copyLectureBlock(String newTitle, LectureBlock block);
 	
+	public LectureBlock moveLectureBlock(LectureBlockRef block, RepositoryEntry newEntry);
+	
 	/**
 	 * Delete the lecture block definitively, the roll calls...
 	 * 
diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
index 27197b748392e44e597a11d93afd50d81b4cd839..692c85fba297e9695e6d526bbe0f68ca25e45345 100644
--- a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
+++ b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
@@ -306,6 +306,16 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable, De
 		return auditLogDao.getAuditLog(entry);
 	}
 
+	@Override
+	public LectureBlock moveLectureBlock(LectureBlockRef block, RepositoryEntry newEntry) {
+		LectureBlockImpl blockToMove = (LectureBlockImpl)lectureBlockDao.loadByKey(block.getKey());
+		blockToMove.setEntry(newEntry);
+		LectureBlock mergedBlock = lectureBlockDao.update(blockToMove);
+		dbInstance.commit();
+		recalculateSummary(mergedBlock.getEntry());
+		return mergedBlock;
+	}
+
 	@Override
 	public LectureBlock copyLectureBlock(String newTitle, LectureBlock block) {
 		LectureBlock copy = lectureBlockDao.createLectureBlock(block.getEntry());
diff --git a/src/main/java/org/olat/modules/lecture/model/LectureBlockImpl.java b/src/main/java/org/olat/modules/lecture/model/LectureBlockImpl.java
index 6596c3de987d799c457871774b70f795b1182219..07c05d119531eb73d6a467caced3dced1eedeb02 100644
--- a/src/main/java/org/olat/modules/lecture/model/LectureBlockImpl.java
+++ b/src/main/java/org/olat/modules/lecture/model/LectureBlockImpl.java
@@ -125,7 +125,7 @@ public class LectureBlockImpl implements Persistable, LectureBlock {
 	private Reason reasonEffectiveEnd;
 	
 	@ManyToOne(targetEntity=RepositoryEntry.class,fetch=FetchType.LAZY,optional=false)
-	@JoinColumn(name="fk_entry", nullable=false, insertable=true, updatable=false)
+	@JoinColumn(name="fk_entry", nullable=false, insertable=true, updatable=true)
 	private RepositoryEntry entry;
 	
 	@ManyToOne(targetEntity=GroupImpl.class,fetch=FetchType.LAZY,optional=false)
diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java
index 1f5fb08d06dd99189996e374d195f5bbf9b663d4..93621c7de262f49113149672284c68f8a995c757 100644
--- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java
+++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java
@@ -34,7 +34,6 @@ import javax.ws.rs.core.Response.Status;
 
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.Group;
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
@@ -44,6 +43,7 @@ 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;
 
 /**
  * 
@@ -58,14 +58,16 @@ public class LectureBlockWebService {
 	private final RepositoryEntry entry;
 	private final LectureBlock lectureBlock;
 	
-	private final LectureService lectureService;
-	private final BaseSecurity securityManager;
+	@Autowired
+	private BaseSecurity securityManager;
+	@Autowired
+	private LectureService lectureService;
+	@Autowired
+	private RepositoryService repositoryService;
 	
-	public LectureBlockWebService(LectureBlock lectureBlock, RepositoryEntry entry, LectureService lectureService) {
+	public LectureBlockWebService(LectureBlock lectureBlock, RepositoryEntry entry) {
 		this.entry = entry;
 		this.lectureBlock = lectureBlock;
-		this.lectureService = lectureService;
-		securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
 	}
 	
 	/**
@@ -83,6 +85,19 @@ public class LectureBlockWebService {
 	public Response getLectureBlock() {
 		return Response.ok(new LectureBlockVO(lectureBlock, entry.getKey())).build();
 	}
+	
+	@POST
+	@Path("entry/{repositoryEntryKey}")
+	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response moveLectureBlock(@PathParam("repositoryEntryKey") Long repositoryEntryKey) {
+		RepositoryEntry newEntry = repositoryService.loadByKey(repositoryEntryKey);
+		if(newEntry == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+		LectureBlock movedLectureBlock = lectureService.moveLectureBlock(lectureBlock, newEntry);
+		return Response.ok(new LectureBlockVO(movedLectureBlock, movedLectureBlock.getEntry().getKey())).build();
+	}
+	
 
 	/**
 	 * Delete a specific lecture blocks.
@@ -163,8 +178,7 @@ public class LectureBlockWebService {
 	@Path("participants/repositoryentry")
 	public Response addRepositoryEntryParticipantGroup() {
 		LectureBlock reloadedBlock = lectureService.getLectureBlock(lectureBlock);
-		Group defGroup = CoreSpringFactory.getImpl(RepositoryService.class)
-				.getDefaultGroup(entry);
+		Group defGroup = repositoryService.getDefaultGroup(entry);
 		List<Group> currentGroups = lectureService.getLectureBlockToGroups(reloadedBlock);
 		if(!currentGroups.contains(defGroup)) {
 			currentGroups.add(defGroup);
@@ -183,8 +197,7 @@ public class LectureBlockWebService {
 	@Path("participants/repositoryentry")
 	public Response deleteRepositoryEntryParticipantGroup() {
 		LectureBlock reloadedBlock = lectureService.getLectureBlock(lectureBlock);
-		Group defGroup = CoreSpringFactory.getImpl(RepositoryService.class)
-				.getDefaultGroup(entry);
+		Group defGroup = repositoryService.getDefaultGroup(entry);
 		List<Group> currentGroups = lectureService.getLectureBlockToGroups(reloadedBlock);
 		if(currentGroups.contains(defGroup)) {
 			currentGroups.remove(defGroup);
diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java
index 62beb7b50b841a34a200658739cdfda9e762361d..89f01a65decc15131a2a2348a9ddbb49befcb538 100644
--- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java
+++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlocksWebService.java
@@ -33,11 +33,13 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+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.core.CoreSpringFactory;
 import org.olat.core.id.Roles;
 import org.olat.modules.lecture.LectureBlock;
 import org.olat.modules.lecture.LectureBlockStatus;
@@ -287,16 +289,19 @@ public class LectureBlocksWebService {
 	 * @return The web service for a single lecture block.
 	 */
 	@Path("{lectureBlockKey}")
-	public LectureBlockWebService getLectureBlockWebService(@PathParam("lectureBlockKey") Long lectureBlockKey, @Context HttpServletRequest httpRequest) {
+	public LectureBlockWebService getLectureBlockWebService(@PathParam("lectureBlockKey") Long lectureBlockKey, @Context HttpServletRequest httpRequest)
+	throws WebApplicationException {
 		Roles roles = getRoles(httpRequest);
 		if(!roles.isOLATAdmin()) {
-			return null;
+			throw new WebApplicationException(Status.UNAUTHORIZED);
 		}
 		LectureBlock lectureBlock = lectureService.getLectureBlock(new LectureBlockRefImpl(lectureBlockKey));
 		if(lectureBlock == null || !lectureBlock.getEntry().equals(entry)) {
-			return null;
+			throw new WebApplicationException(Status.NOT_FOUND);
 		}
-		return new LectureBlockWebService(lectureBlock, entry, lectureService);
+		LectureBlockWebService ws = new LectureBlockWebService(lectureBlock, entry);
+		CoreSpringFactory.autowireObject(ws);
+		return ws;
 	}
 	
 	/**
diff --git a/src/main/java/org/olat/restapi/repository/CatalogWebService.java b/src/main/java/org/olat/restapi/repository/CatalogWebService.java
index 1458f8db7730d9b6fffeffa0ce61f7752a13bc8b..962aa893f93c7775f10fa256310d052de3b393aa 100644
--- a/src/main/java/org/olat/restapi/repository/CatalogWebService.java
+++ b/src/main/java/org/olat/restapi/repository/CatalogWebService.java
@@ -53,7 +53,6 @@ import javax.ws.rs.core.UriInfo;
 
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.manager.SecurityGroupDAO;
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
@@ -75,6 +74,7 @@ import org.olat.restapi.support.vo.ErrorVO;
 import org.olat.user.UserManager;
 import org.olat.user.restapi.UserVO;
 import org.olat.user.restapi.UserVOFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 /**
@@ -91,11 +91,17 @@ public class CatalogWebService {
 	
 	private static final String VERSION = "1.0";
 	
-	private final CatalogManager catalogManager;
-	
-	public CatalogWebService() {
-		catalogManager = CoreSpringFactory.getImpl(CatalogManager.class);
-	}
+	@Autowired
+	private UserManager userManager;
+	@Autowired
+	private BaseSecurity securityManager;
+	@Autowired
+	private CatalogManager catalogManager;
+	@Autowired
+	private SecurityGroupDAO securityGroupDao;
+	@Autowired
+	private RepositoryManager repositoryManager;
+
 	
 	/**
 	 * Retrieves the version of the Catalog Web Service.
@@ -310,7 +316,7 @@ public class CatalogWebService {
 		
 		RepositoryEntry re = null;
 		if(entryVo.getRepositoryEntryKey() != null) {
-			re = RepositoryManager.getInstance().lookupRepositoryEntry(entryVo.getRepositoryEntryKey());
+			re = repositoryManager.lookupRepositoryEntry(entryVo.getRepositoryEntryKey());
 			if(re == null) {
 				return Response.serverError().status(Status.NOT_FOUND).build();
 			}
@@ -649,7 +655,6 @@ public class CatalogWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
 		Identity identity = securityManager.loadIdentityByKey(identityKey, false);
 		if(identity == null) {
 			return Response.serverError().status(Status.NOT_FOUND).build();
@@ -662,7 +667,7 @@ public class CatalogWebService {
 		}
 		
 		try {
-			CoreSpringFactory.getImpl(SecurityGroupDAO.class).addIdentityToSecurityGroup(identity, ce.getOwnerGroup());
+			securityGroupDao.addIdentityToSecurityGroup(identity, ce.getOwnerGroup());
 		} catch(Exception e) {
 			throw new WebApplicationException(e);
 		} finally {
@@ -702,7 +707,6 @@ public class CatalogWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
 		Identity identity = securityManager.loadIdentityByKey(identityKey, false);
 		if(identity == null) {
 			return Response.ok().build();
@@ -736,7 +740,7 @@ public class CatalogWebService {
 		
 		Translator translator = Util.createPackageTranslator(CatalogNodeManagerController.class, locale);
 
-		String ownerName = CoreSpringFactory.getImpl(UserManager.class).getUserDisplayName(lock.getOwner());
+		String ownerName = userManager.getUserDisplayName(lock.getOwner());
 		String translation = translator.translate("catalog.locked.by", new String[]{ ownerName });
 		ErrorVO vo = new ErrorVO("org.olat.catalog.ui","catalog.locked.by",translation);
 		ErrorVO[] voes = new ErrorVO[]{vo};
diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java b/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java
index c18215fae2bb1fcf5423a76525e04fe67fc543f5..69487a03c5f74ec31596a227bd414472e8609ef9 100644
--- a/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java
+++ b/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java
@@ -43,6 +43,7 @@ import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 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;
@@ -118,9 +119,9 @@ public class RepositoryEntriesWebService {
 	/**
 	 * List all entries in the OLAT repository
 	 * @response.representation.200.qname {http://www.example.com}repositoryEntryVO
-   * @response.representation.200.mediaType text/plain, text/html, application/xml, application/json
-   * @response.representation.200.doc List all entries in the repository
-   * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_REPOENTRYVOes}
+	 * @response.representation.200.mediaType text/plain, text/html, application/xml, application/json
+	 * @response.representation.200.doc List all entries in the repository
+	 * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_REPOENTRYVOes}
 	 * @param uriInfo The URI information
 	 * @param httpRequest The HTTP request
 	 * @return
@@ -158,9 +159,9 @@ public class RepositoryEntriesWebService {
 	/**
 	 * List all entries in the OLAT repository
 	 * @response.representation.200.qname {http://www.example.com}repositoryEntryVO
-   * @response.representation.200.mediaType text/plain, text/html, application/xml, application/json
-   * @response.representation.200.doc List all entries in the repository
-   * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_REPOENTRYVOes}
+	 * @response.representation.200.mediaType text/plain, text/html, application/xml, application/json
+	 * @response.representation.200.doc List all entries in the repository
+	 * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_REPOENTRYVOes}
 	 * @param start (optional)
 	 * @param limit (optional)
 	 * @param managed (optional)
@@ -387,9 +388,30 @@ public class RepositoryEntriesWebService {
 	}
 	
 	@Path("{repoEntryKey}")
-	public RepositoryEntryWebService getRepositoryEntryResource() {
-		RepositoryEntryWebService entrySW = new RepositoryEntryWebService();
+	public RepositoryEntryWebService getRepositoryEntryResource(@PathParam("repoEntryKey")String repoEntryKey)
+	throws WebApplicationException {
+		RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
+	    if(re == null) {
+	      throw new WebApplicationException(Status.NOT_FOUND);
+	    }
+		
+		RepositoryEntryWebService entrySW = new RepositoryEntryWebService(re);
 		CoreSpringFactory.autowireObject(entrySW);
 		return entrySW;
 	}
+	
+	private RepositoryEntry lookupRepositoryEntry(String key) {
+		RepositoryEntry re = null;
+		if (StringHelper.isLong(key)) {// looks like a primary key
+			try {
+				re = repositoryManager.lookupRepositoryEntry(Long.valueOf(key));
+			} catch (NumberFormatException e) {
+				log.warn("", e);
+			}
+		}
+		if (re == null) {// perhaps a soft key
+			re = repositoryManager.lookupRepositoryEntryBySoftkey(key, false);
+		}
+		return re;
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntryLifecycleWebService.java b/src/main/java/org/olat/restapi/repository/RepositoryEntryLifecycleWebService.java
index 58dececc0b51505c135c28ea4a3c201be136832f..264f915fbb6d6b5430576b5cb49f1c6a1359cf0c 100644
--- a/src/main/java/org/olat/restapi/repository/RepositoryEntryLifecycleWebService.java
+++ b/src/main/java/org/olat/restapi/repository/RepositoryEntryLifecycleWebService.java
@@ -33,11 +33,11 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Roles;
 import org.olat.repository.manager.RepositoryEntryLifecycleDAO;
 import org.olat.repository.model.RepositoryEntryLifecycle;
 import org.olat.restapi.support.vo.RepositoryEntryLifecycleVO;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 /**
@@ -50,6 +50,9 @@ import org.springframework.stereotype.Component;
 @Path("repo/lifecycle")
 public class RepositoryEntryLifecycleWebService {
 	
+	@Autowired
+	private RepositoryEntryLifecycleDAO lifeCycleDao;
+	
 	/**
 	 * List all public lifecycles
 	 * @response.representation.200.qname {http://www.example.com}repositoryEntryVO
@@ -68,7 +71,6 @@ public class RepositoryEntryLifecycleWebService {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		RepositoryEntryLifecycleDAO lifeCycleDao = CoreSpringFactory.getImpl(RepositoryEntryLifecycleDAO.class);
 		List<RepositoryEntryLifecycle> publicLifeCycles = lifeCycleDao.loadPublicLifecycle();
 		List<RepositoryEntryLifecycleVO> voList = new ArrayList<>(publicLifeCycles.size());
 		for(RepositoryEntryLifecycle lifeCycle: publicLifeCycles) {
diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java b/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java
index f2e78aa9d4e86a38a34883770b1da599783252a2..60c7cefec408d131731fea2cd6a757725cf56e44 100644
--- a/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java
+++ b/src/main/java/org/olat/restapi/repository/RepositoryEntryWebService.java
@@ -48,6 +48,7 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.CacheControl;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.EntityTag;
@@ -88,6 +89,7 @@ import org.olat.resource.OLATResourceManager;
 import org.olat.restapi.security.RestSecurityHelper;
 import org.olat.restapi.support.MultipartReader;
 import org.olat.restapi.support.ObjectFactory;
+import org.olat.restapi.support.vo.RepositoryEntryAccessVO;
 import org.olat.restapi.support.vo.RepositoryEntryLifecycleVO;
 import org.olat.restapi.support.vo.RepositoryEntryVO;
 import org.olat.user.restapi.UserVO;
@@ -108,18 +110,24 @@ public class RepositoryEntryWebService {
   private static final OLog log = Tracing.createLoggerFor(RepositoryEntryWebService.class);
 
 	public static CacheControl cc = new CacheControl();
-
 	static {
 		cc.setMaxAge(-1);
 	}
 	
+	private RepositoryEntry entry;
+	
 	@Autowired
 	private RepositoryManager repositoryManager;
 	@Autowired
 	private RepositoryService repositoryService;
 	@Autowired
 	private BaseSecurity securityManager;
- 
+	@Autowired
+	private 	RepositoryEntryLifecycleDAO lifecycleDao;
+	
+	public RepositoryEntryWebService(RepositoryEntry entry) {
+		this.entry = entry;
+	}
 
   /**
    * get a resource in the repository
@@ -132,34 +140,28 @@ public class RepositoryEntryWebService {
    * @param request The REST request
    * @return
    */
-  @GET
-  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-  public Response getById(@PathParam("repoEntryKey")String repoEntryKey, @Context Request request){
-    RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
-    if(re == null) {
-      return Response.serverError().status(Status.NOT_FOUND).build();
-    }
-
-    Date lastModified = re.getLastModified();
-
-    Response.ResponseBuilder response;
-    if(lastModified == null) {
-      EntityTag eTag = ObjectFactory.computeEtag(re);
-      response = request.evaluatePreconditions(eTag);
-      if(response == null) {
-        RepositoryEntryVO vo = RepositoryEntryVO.valueOf(re);
-        response = Response.ok(vo).tag(eTag).lastModified(lastModified);
-      }
-    } else {
-      EntityTag eTag = ObjectFactory.computeEtag(re);
-      response = request.evaluatePreconditions(lastModified, eTag);
-      if(response == null) {
-        RepositoryEntryVO vo = RepositoryEntryVO.valueOf(re);
-        response = Response.ok(vo).tag(eTag).lastModified(lastModified);
-      }
-    }
-    return response.build();
-  }
+	@GET
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response getById(@Context Request request) {
+		Date lastModified = entry.getLastModified();
+		Response.ResponseBuilder response;
+		if (lastModified == null) {
+			EntityTag eTag = ObjectFactory.computeEtag(entry);
+			response = request.evaluatePreconditions(eTag);
+			if (response == null) {
+				RepositoryEntryVO vo = RepositoryEntryVO.valueOf(entry);
+				response = Response.ok(vo).tag(eTag).lastModified(lastModified);
+			}
+		} else {
+			EntityTag eTag = ObjectFactory.computeEtag(entry);
+			response = request.evaluatePreconditions(lastModified, eTag);
+			if (response == null) {
+				RepositoryEntryVO vo = RepositoryEntryVO.valueOf(entry);
+				response = Response.ok(vo).tag(eTag).lastModified(lastModified);
+			}
+		}
+		return response.build();
+	}
   
 	/**
 	 * To get the web service for the lecture blocks of a specific learning resource.
@@ -168,10 +170,9 @@ public class RepositoryEntryWebService {
 	 * @return The web service for lecture blocks.
 	 */
 	@Path("lectureblocks")
-	public LectureBlocksWebService getLectureBlocksWebService(@PathParam("repoEntryKey")String repoEntryKey) {
-	    RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
-	    if(re == null) return null;
-		LectureBlocksWebService service = new LectureBlocksWebService(re);
+	public LectureBlocksWebService getLectureBlocksWebService()
+	throws WebApplicationException {
+		LectureBlocksWebService service = new LectureBlocksWebService(entry);
 		CoreSpringFactory.autowireObject(service);
 		return service;
 	}
@@ -190,14 +191,11 @@ public class RepositoryEntryWebService {
 	@GET
 	@Path("owners")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-	public Response getOwners(@PathParam("repoEntryKey") String repoEntryKey, @Context HttpServletRequest request) {
-		RepositoryEntry repoEntry = lookupRepositoryEntry(repoEntryKey);
-		if(repoEntry == null) {
-			return Response.serverError().status(Status.NOT_FOUND).build();
-		} else if(!isAuthorEditor(repoEntry, request)) {
+	public Response getOwners(@Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
-		return getIdentityInSecurityGroup(repoEntry, GroupRoles.owner.name());
+		return getIdentityInSecurityGroup(entry, GroupRoles.owner.name());
 	}
 	
 	/**
@@ -212,53 +210,35 @@ public class RepositoryEntryWebService {
 	 */
 	@PUT
 	@Path("owners/{identityKey}")
-	public Response addOwner(@PathParam("repoEntryKey") String repoEntryKey, @PathParam("identityKey") Long identityKey,
-			@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();
-			}
-			
-			Identity identityToAdd = securityManager.loadIdentityByKey(identityKey);
-			if(identityToAdd == null) {
-				return Response.serverError().status(Status.NOT_FOUND).build();
-			}
-
-			UserRequest ureq = RestSecurityHelper.getUserRequest(request);
-			IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
-			repositoryManager.addOwners(ureq.getIdentity(), iae, repoEntry, new MailPackage(false));
-			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();
+	public Response addOwner(@PathParam("identityKey") Long identityKey, @Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
+		
+		Identity identityToAdd = securityManager.loadIdentityByKey(identityKey);
+		if(identityToAdd == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+
+		UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+		IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
+		repositoryManager.addOwners(ureq.getIdentity(), iae, entry, new MailPackage(false));
+		return Response.ok().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, new MailPackage(false));
-			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();
+	public Response addOwners(UserVO[] owners, @Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, 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, entry, new MailPackage(false));
+		return Response.ok().build();
 	}
 	
 	/**
@@ -273,12 +253,9 @@ public class RepositoryEntryWebService {
 	 */
 	@DELETE
 	@Path("owners/{identityKey}")
-	public Response removeOwner(@PathParam("repoEntryKey") String repoEntryKey, @PathParam("identityKey") Long identityKey, @Context HttpServletRequest request) {
+	public Response removeOwner(@PathParam("identityKey") Long identityKey, @Context HttpServletRequest request) {
 		try {
-			RepositoryEntry repoEntry = lookupRepositoryEntry(repoEntryKey);
-			if(repoEntry == null) {
-				return Response.serverError().status(Status.NOT_FOUND).build();
-			} else if (!isAuthorEditor(repoEntry, request)) {
+			if (!isAuthorEditor(entry, request)) {
 				return Response.serverError().status(Status.UNAUTHORIZED).build();
 			}
 
@@ -288,7 +265,7 @@ public class RepositoryEntryWebService {
 			}
 
 			final UserRequest ureq = RestSecurityHelper.getUserRequest(request);
-			repositoryManager.removeOwners(ureq.getIdentity(), Collections.singletonList(identityToRemove), repoEntry, new MailPackage(false));
+			repositoryManager.removeOwners(ureq.getIdentity(), Collections.singletonList(identityToRemove), entry, new MailPackage(false));
 			return Response.ok().build();
 		} catch (Exception e) {
 			log.error("Trying to remove an owner to a repository entry", e);
@@ -310,14 +287,11 @@ public class RepositoryEntryWebService {
 	@GET
 	@Path("coaches")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-	public Response getCoaches(@PathParam("repoEntryKey") String repoEntryKey, @Context HttpServletRequest request) {
-		RepositoryEntry repoEntry = lookupRepositoryEntry(repoEntryKey);
-		if(repoEntry == null) {
-			return Response.serverError().status(Status.NOT_FOUND).build();
-		} else if(!isAuthorEditor(repoEntry, request)) {
+	public Response getCoaches(@Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
-		return getIdentityInSecurityGroup(repoEntry, GroupRoles.coach.name());
+		return getIdentityInSecurityGroup(entry, GroupRoles.coach.name());
 	}
 	
 	/**
@@ -332,53 +306,36 @@ public class RepositoryEntryWebService {
 	 */
 	@PUT
 	@Path("coaches/{identityKey}")
-	public Response addCoach(@PathParam("repoEntryKey") String repoEntryKey, @PathParam("identityKey") Long identityKey,
+	public Response addCoach(@PathParam("identityKey") Long identityKey,
 			@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();
-			}
-			
-			Identity identityToAdd = securityManager.loadIdentityByKey(identityKey);
-			if(identityToAdd == null) {
-				return Response.serverError().status(Status.NOT_FOUND).build();
-			}
-
-			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();
+		if(!isAuthorEditor(entry, request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
+		
+		Identity identityToAdd = securityManager.loadIdentityByKey(identityKey);
+		if(identityToAdd == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
+		}
+
+		UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+		IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
+		repositoryManager.addTutors(ureq.getIdentity(), ureq.getUserSession().getRoles(), iae, entry, null);
+		return Response.ok().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();
+	public Response addCoach(UserVO[] coaches, @Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, 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, entry, null);
+		return Response.ok().build();
 	}
 	
 	/**
@@ -393,27 +350,19 @@ public class RepositoryEntryWebService {
 	 */
 	@DELETE
 	@Path("coaches/{identityKey}")
-	public Response removeCoach(@PathParam("repoEntryKey") String repoEntryKey, @PathParam("identityKey") Long identityKey, @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();
-			}
-
-			Identity identityToRemove = securityManager.loadIdentityByKey(identityKey);
-			if(identityToRemove == null) {
-				return Response.serverError().status(Status.NOT_FOUND).build();
-			}
+	public Response removeCoach(@PathParam("identityKey") Long identityKey, @Context HttpServletRequest request) {
+		if (!isAuthorEditor(entry, request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
 
-			final UserRequest ureq = RestSecurityHelper.getUserRequest(request);
-			repositoryManager.removeTutors(ureq.getIdentity(), Collections.singletonList(identityToRemove), repoEntry, new MailPackage(false));
-			return Response.ok().build();
-		} catch (Exception e) {
-			log.error("Trying to remove a coach from a repository entry", e);
-			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		Identity identityToRemove = securityManager.loadIdentityByKey(identityKey);
+		if(identityToRemove == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
 		}
+
+		final UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+		repositoryManager.removeTutors(ureq.getIdentity(), Collections.singletonList(identityToRemove), entry, new MailPackage(false));
+		return Response.ok().build();
 	}
 	
 	/**
@@ -430,14 +379,11 @@ public class RepositoryEntryWebService {
 	@GET
 	@Path("participants")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-	public Response getParticipants(@PathParam("repoEntryKey") String repoEntryKey, @Context HttpServletRequest request) {
-		RepositoryEntry repoEntry = lookupRepositoryEntry(repoEntryKey);
-		if(repoEntry == null) {
-			return Response.serverError().status(Status.NOT_FOUND).build();
-		} else if(!isAuthorEditor(repoEntry, request)) {
+	public Response getParticipants( @Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
-		return getIdentityInSecurityGroup(repoEntry, GroupRoles.participant.name());
+		return getIdentityInSecurityGroup(entry, GroupRoles.participant.name());
 	}
 	
 	/**
@@ -452,53 +398,35 @@ public class RepositoryEntryWebService {
 	 */
 	@PUT
 	@Path("participants/{identityKey}")
-	public Response addParticipant(@PathParam("repoEntryKey") String repoEntryKey, @PathParam("identityKey") Long identityKey,
-			@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();
-			}
-			
-			Identity identityToAdd = securityManager.loadIdentityByKey(identityKey);
-			if(identityToAdd == null) {
-				return Response.serverError().status(Status.NOT_FOUND).build();
-			}
-
-			UserRequest ureq = RestSecurityHelper.getUserRequest(request);
-			IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
-			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();
+	public Response addParticipant(@PathParam("identityKey") Long identityKey, @Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		
+		Identity identityToAdd = securityManager.loadIdentityByKey(identityKey);
+		if(identityToAdd == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
 		}
+
+		UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+		IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
+		repositoryManager.addParticipants(ureq.getIdentity(), ureq.getUserSession().getRoles(), iae, entry, null);
+		return Response.ok().build();
 	}
 	
 	@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();
+	public Response addParticipants(UserVO[] participants, @Context HttpServletRequest request) {
+		if(!isAuthorEditor(entry, 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, entry, null);
+		return Response.ok().build();
 	}
 	
 	private List<Identity> loadIdentities(UserVO[] users) {
@@ -521,28 +449,19 @@ public class RepositoryEntryWebService {
 	 */
 	@DELETE
 	@Path("participants/{identityKey}")
-	public Response removeParticipant(@PathParam("repoEntryKey") String repoEntryKey, @PathParam("identityKey") Long identityKey,
-			@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();
-			}
-
-			Identity identityToRemove = securityManager.loadIdentityByKey(identityKey);
-			if(identityToRemove == null) {
-				return Response.serverError().status(Status.NOT_FOUND).build();
-			}
+	public Response removeParticipant(@PathParam("identityKey") Long identityKey, @Context HttpServletRequest request) {
+		if (!isAuthorEditor(entry, request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
 
-			final UserRequest ureq = RestSecurityHelper.getUserRequest(request);
-			repositoryManager.removeParticipants(ureq.getIdentity(), Collections.singletonList(identityToRemove), repoEntry, null, false);
-			return Response.ok().build();
-		} catch (Exception e) {
-			log.error("Trying to remove a participant from a repository entry", e);
-			return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+		Identity identityToRemove = securityManager.loadIdentityByKey(identityKey);
+		if(identityToRemove == null) {
+			return Response.serverError().status(Status.NOT_FOUND).build();
 		}
+
+		final UserRequest ureq = RestSecurityHelper.getUserRequest(request);
+		repositoryManager.removeParticipants(ureq.getIdentity(), Collections.singletonList(identityToRemove), entry, null, false);
+		return Response.ok().build();
 	}
 
   /**
@@ -563,26 +482,20 @@ public class RepositoryEntryWebService {
 	@GET
 	@Path("file")
 	@Produces({ "application/zip", MediaType.APPLICATION_OCTET_STREAM })
-	public Response getRepoFileById(@PathParam("repoEntryKey") String repoEntryKey,
-			@Context HttpServletRequest request, @Context HttpServletResponse response) {
-		RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
-		if (re == null) {
-			return Response.serverError().status(Status.NOT_FOUND).build();
-		}
-
-		RepositoryHandler typeToDownload = RepositoryHandlerFactory.getInstance().getRepositoryHandler(re);
+	public Response getRepoFileById(@Context HttpServletRequest request, @Context HttpServletResponse response) {
+		RepositoryHandler typeToDownload = RepositoryHandlerFactory.getInstance().getRepositoryHandler(entry);
 		if (typeToDownload == null) {
 			return Response.serverError().status(Status.NOT_FOUND).build();
 		}
 
-		OLATResource ores = OLATResourceManager.getInstance().findResourceable(re.getOlatResource());
+		OLATResource ores = OLATResourceManager.getInstance().findResourceable(entry.getOlatResource());
 		if (ores == null) {
 			return Response.serverError().status(Status.NOT_FOUND).build();
 		}
 
 		Identity identity = getIdentity(request);
-		boolean canDownload = re.getCanDownload() && typeToDownload.supportsDownload();
-		if (isAdmin(request) || RepositoryManager.getInstance().isOwnerOfRepositoryEntry(identity, re)) {
+		boolean canDownload = entry.getCanDownload() && typeToDownload.supportsDownload();
+		if (isAdmin(request) || RepositoryManager.getInstance().isOwnerOfRepositoryEntry(identity, entry)) {
 			canDownload = true;
 		} else if(!isAuthor(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
@@ -599,7 +512,7 @@ public class RepositoryEntryWebService {
 			if (lockResult == null || (lockResult.isSuccess() && !isAlreadyLocked)) {
 				MediaResource mr = typeToDownload.getAsMediaResource(ores, false);
 				if (mr != null) {
-					repositoryService.incrementDownloadCounter(re);
+					repositoryService.incrementDownloadCounter(entry);
 					InputStream in = mr.getInputStream();
 					if(in == null) {
 						mr.prepare(response);
@@ -620,56 +533,49 @@ public class RepositoryEntryWebService {
 		}
 	}
   
-  @POST
-  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-  @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-  public Response updateEntry(@PathParam("repoEntryKey") String repoEntryKey,
-      RepositoryEntryVO vo, @Context HttpServletRequest request) {
-    if(!RestSecurityHelper.isAuthor(request)) {
-      return Response.serverError().status(Status.UNAUTHORIZED).build();
-    }
-    
-    final RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
-    if(re == null) {
-      return Response.serverError().status(Status.NOT_FOUND).build();
-    }
-    
-    RepositoryEntryLifecycle lifecycle = null;
-    RepositoryEntryLifecycleVO lifecycleVo = vo.getLifecycle();
-    if(lifecycleVo != null) {
-    	RepositoryEntryLifecycleDAO lifecycleDao = CoreSpringFactory.getImpl(RepositoryEntryLifecycleDAO.class);
-    	if(lifecycleVo.getKey() != null) {
-    		lifecycle = lifecycleDao.loadById(lifecycleVo.getKey());
-    		if(lifecycle.isPrivateCycle()) {
-    			//check date
-      		String fromStr = lifecycleVo.getValidFrom();
-      		String toStr = lifecycleVo.getValidTo();
-      		String label = lifecycleVo.getLabel();
-      		String softKey = lifecycleVo.getSoftkey();
-    			Date from = ObjectFactory.parseDate(fromStr);
-      		Date to = ObjectFactory.parseDate(toStr);
-      		lifecycle.setLabel(label);
-      		lifecycle.setSoftKey(softKey);
-      		lifecycle.setValidFrom(from);
-      		lifecycle.setValidTo(to);
-    		}
-    	} else {
-    		String fromStr = lifecycleVo.getValidFrom();
-    		String toStr = lifecycleVo.getValidTo();
-    		String label = lifecycleVo.getLabel();
-    		String softKey = lifecycleVo.getSoftkey();
-    		Date from = ObjectFactory.parseDate(fromStr);
-    		Date to = ObjectFactory.parseDate(toStr);
-    		lifecycle = lifecycleDao.create(label, softKey, true, from, to);
-    	}
-    }
-
-    RepositoryEntry reloaded = repositoryManager.setDescriptionAndName(re, vo.getDisplayname(), vo.getDescription(),
-    		vo.getLocation(), vo.getAuthors(), vo.getExternalId(), vo.getExternalRef(), vo.getManagedFlags(),
-    		lifecycle);
-    RepositoryEntryVO rvo = RepositoryEntryVO.valueOf(reloaded);
-    return Response.ok(rvo).build();
-  }
+	@POST
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response updateEntry(RepositoryEntryVO vo, @Context HttpServletRequest request) {
+		if (!RestSecurityHelper.isAuthor(request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+
+		RepositoryEntryLifecycle lifecycle = null;
+		RepositoryEntryLifecycleVO lifecycleVo = vo.getLifecycle();
+		if (lifecycleVo != null) {
+			if (lifecycleVo.getKey() != null) {
+				lifecycle = lifecycleDao.loadById(lifecycleVo.getKey());
+				if (lifecycle.isPrivateCycle()) {
+					// check date
+					String fromStr = lifecycleVo.getValidFrom();
+					String toStr = lifecycleVo.getValidTo();
+					String label = lifecycleVo.getLabel();
+					String softKey = lifecycleVo.getSoftkey();
+					Date from = ObjectFactory.parseDate(fromStr);
+					Date to = ObjectFactory.parseDate(toStr);
+					lifecycle.setLabel(label);
+					lifecycle.setSoftKey(softKey);
+					lifecycle.setValidFrom(from);
+					lifecycle.setValidTo(to);
+				}
+			} else {
+				String fromStr = lifecycleVo.getValidFrom();
+				String toStr = lifecycleVo.getValidTo();
+				String label = lifecycleVo.getLabel();
+				String softKey = lifecycleVo.getSoftkey();
+				Date from = ObjectFactory.parseDate(fromStr);
+				Date to = ObjectFactory.parseDate(toStr);
+				lifecycle = lifecycleDao.create(label, softKey, true, from, to);
+			}
+		}
+
+		RepositoryEntry reloaded = repositoryManager.setDescriptionAndName(entry, vo.getDisplayname(), vo.getDescription(),
+				vo.getLocation(), vo.getAuthors(), vo.getExternalId(), vo.getExternalRef(), vo.getManagedFlags(),
+				lifecycle);
+		RepositoryEntryVO rvo = RepositoryEntryVO.valueOf(reloaded);
+		return Response.ok(rvo).build();
+	}
 
   /**
    * Replace a resource in the repository and update its display name. The implementation is
@@ -688,59 +594,53 @@ public class RepositoryEntryWebService {
    * @param request The HTTP request
    * @return
    */
-  @POST
-  @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-  @Consumes({MediaType.MULTIPART_FORM_DATA})
-  public Response replaceResource(@PathParam("repoEntryKey") String repoEntryKey,
-      @Context HttpServletRequest request) {
-    if(!RestSecurityHelper.isAuthor(request)) {
-      return Response.serverError().status(Status.UNAUTHORIZED).build();
-    }
-
-    MultipartReader reader = null;
-    try {
-      final RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
-      if(re == null) {
-        return Response.serverError().status(Status.NOT_FOUND).build();
-      }
-      
-      reader = new MultipartReader(request);
-      File tmpFile = reader.getFile();
-      String displayname = reader.getValue("displayname");
-      String location = reader.getValue("location");
-      String authors = reader.getValue("authors");
-      String description = reader.getValue("description");
-      String externalId = reader.getValue("externalId");
-      String externalRef = reader.getValue("externalRef");
-      String managedFlags = reader.getValue("managedFlags");
-
-      Identity identity = RestSecurityHelper.getUserRequest(request).getIdentity();
-      RepositoryEntry replacedRe;
-      if(tmpFile == null) {
-      	replacedRe = repositoryManager.setDescriptionAndName(re, displayname, description,
-      			location, authors, externalId, externalRef, managedFlags, re.getLifecycle());
-      } else {
-	      long length = tmpFile.length();
-	      if(length == 0) {
-	        return Response.serverError().status(Status.NO_CONTENT).build();
-	      }
-	      replacedRe = replaceFileResource(identity, re, tmpFile);
-	      if(replacedRe == null) {
-	        return Response.serverError().status(Status.NOT_FOUND).build();
-	      } else {
-	      	replacedRe = repositoryManager.setDescriptionAndName(replacedRe, displayname, description,
-	      			location, authors, externalId, externalRef, managedFlags, replacedRe.getLifecycle());
-	      }
-      }
-      RepositoryEntryVO vo = RepositoryEntryVO.valueOf(replacedRe);
-      return Response.ok(vo).build();
-    } catch (Exception e) {
-      log.error("Error while importing a file",e);
-    } finally {
-    	MultipartReader.closeQuietly(reader);
-    }
-    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
-  }
+	@POST
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Consumes({ MediaType.MULTIPART_FORM_DATA })
+	public Response replaceResource(@Context HttpServletRequest request) {
+		if (!RestSecurityHelper.isAuthor(request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+
+		MultipartReader reader = null;
+		try {
+			reader = new MultipartReader(request);
+			File tmpFile = reader.getFile();
+			String displayname = reader.getValue("displayname");
+			String location = reader.getValue("location");
+			String authors = reader.getValue("authors");
+			String description = reader.getValue("description");
+			String externalId = reader.getValue("externalId");
+			String externalRef = reader.getValue("externalRef");
+			String managedFlags = reader.getValue("managedFlags");
+
+			Identity identity = RestSecurityHelper.getUserRequest(request).getIdentity();
+			RepositoryEntry replacedRe;
+			if (tmpFile == null) {
+				replacedRe = repositoryManager.setDescriptionAndName(entry, displayname, description, location, authors,
+						externalId, externalRef, managedFlags, entry.getLifecycle());
+			} else {
+				long length = tmpFile.length();
+				if (length == 0) {
+					return Response.serverError().status(Status.NO_CONTENT).build();
+				}
+				replacedRe = replaceFileResource(identity, entry, tmpFile);
+				if (replacedRe == null) {
+					return Response.serverError().status(Status.NOT_FOUND).build();
+				} else {
+					replacedRe = repositoryManager.setDescriptionAndName(replacedRe, displayname, description, location,
+							authors, externalId, externalRef, managedFlags, replacedRe.getLifecycle());
+				}
+			}
+			RepositoryEntryVO vo = RepositoryEntryVO.valueOf(replacedRe);
+			return Response.ok(vo).build();
+		} catch (Exception e) {
+			log.error("Error while importing a file", e);
+		} finally {
+			MultipartReader.closeQuietly(reader);
+		}
+		return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	}
 
 	private RepositoryEntry replaceFileResource(Identity identity, RepositoryEntry re, File fResource) {
 		if (re == null) throw new NullPointerException("RepositoryEntry cannot be null");
@@ -786,25 +686,21 @@ public class RepositoryEntryWebService {
 	 */
 	@DELETE
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
-	public Response deleteCourse(@PathParam("repoEntryKey") String repoEntryKey, @Context HttpServletRequest request) {
+	public Response deleteCourse(@Context HttpServletRequest request) {
 		if(!isAuthor(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 
-		RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
-		if(re == null) {
-			return Response.serverError().status(Status.NOT_FOUND).build();
-		} else if (!isAuthorEditor(re, request)) {
+		if (!isAuthorEditor(entry, request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		UserRequest ureq = getUserRequest(request);
-		RepositoryService rs = CoreSpringFactory.getImpl(RepositoryService.class);
-		ErrorList errors = rs.deletePermanently(re, ureq.getIdentity(), ureq.getUserSession().getRoles(), ureq.getLocale());
+		ErrorList errors = repositoryService.deletePermanently(entry, ureq.getIdentity(), ureq.getUserSession().getRoles(), ureq.getLocale());
 		if(errors.hasErrors()) {
 			return Response.serverError().status(500).build();
 		}
 		ThreadLocalUserActivityLogger.log(LearningResourceLoggingAction.LEARNING_RESOURCE_DELETE, getClass(),
-				LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry));
+				LoggingResourceable.wrap(entry, OlatResourceableType.genRepoEntry));
 		return Response.ok().build();
 	}
 	
@@ -828,51 +724,70 @@ public class RepositoryEntryWebService {
 	@POST
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
 	@Path("status")
-	public Response deleteCoursePermanently(@PathParam("repoEntryKey") String repoEntryKey,
-			@FormParam("newStatus") String newStatus, @Context HttpServletRequest request) {
-		
+	public Response deleteCoursePermanently(@FormParam("newStatus") String newStatus, @Context HttpServletRequest request) {
 		if(!isAuthor(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
-		
-		RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
-		if(re == null) {
-			return Response.serverError().status(Status.NOT_FOUND).build();
-		} else if (!isAuthorEditor(re, request)) {
+		if (!isAuthorEditor(entry, request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
 		
-		RepositoryService rs = CoreSpringFactory.getImpl(RepositoryService.class);
 		if("closed".equals(newStatus)) {
-			rs.closeRepositoryEntry(re);
-			log.audit("REST closing course: " + re.getDisplayname() + " [" + re.getKey() + "]");
+			repositoryService.closeRepositoryEntry(entry);
+			log.audit("REST closing course: " + entry.getDisplayname() + " [" + entry.getKey() + "]");
 			ThreadLocalUserActivityLogger.log(LearningResourceLoggingAction.LEARNING_RESOURCE_CLOSE, getClass(),
-					LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry));
+					LoggingResourceable.wrap(entry, OlatResourceableType.genRepoEntry));
 		} else if("unclosed".equals(newStatus)) {
-			rs.uncloseRepositoryEntry(re);
-			log.audit("REST unclosing course: " + re.getDisplayname() + " [" + re.getKey() + "]");
+			repositoryService.uncloseRepositoryEntry(entry);
+			log.audit("REST unclosing course: " + entry.getDisplayname() + " [" + entry.getKey() + "]");
 			ThreadLocalUserActivityLogger.log(LearningResourceLoggingAction.LEARNING_RESOURCE_UPDATE, getClass(),
-					LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry));
+					LoggingResourceable.wrap(entry, OlatResourceableType.genRepoEntry));
 		} else if("unpublished".equals(newStatus)) {
-			rs.unpublishRepositoryEntry(re);
-			log.audit("REST unpublishing course: " + re.getDisplayname() + " [" + re.getKey() + "]");
+			repositoryService.unpublishRepositoryEntry(entry);
+			log.audit("REST unpublishing course: " + entry.getDisplayname() + " [" + entry.getKey() + "]");
 			ThreadLocalUserActivityLogger.log(LearningResourceLoggingAction.LEARNING_RESOURCE_DEACTIVATE, getClass(),
-					LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry));
+					LoggingResourceable.wrap(entry, OlatResourceableType.genRepoEntry));
 		} else if("deleted".equals(newStatus)) {
 			Identity identity = getIdentity(request);
-			rs.deleteSoftly(re, identity, true);
-			log.audit("REST deleting (soft) course: " + re.getDisplayname() + " [" + re.getKey() + "]");
+			repositoryService.deleteSoftly(entry, identity, true);
+			log.audit("REST deleting (soft) course: " + entry.getDisplayname() + " [" + entry.getKey() + "]");
 			ThreadLocalUserActivityLogger.log(LearningResourceLoggingAction.LEARNING_RESOURCE_TRASH, getClass(),
-					LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry));
+					LoggingResourceable.wrap(entry, OlatResourceableType.genRepoEntry));
 		} else if("restored".equals(newStatus)) {
-			rs.restoreRepositoryEntry(re);
-			log.audit("REST restoring course: " + re.getDisplayname() + " [" + re.getKey() + "]");
+			repositoryService.restoreRepositoryEntry(entry);
+			log.audit("REST restoring course: " + entry.getDisplayname() + " [" + entry.getKey() + "]");
 			ThreadLocalUserActivityLogger.log(LearningResourceLoggingAction.LEARNING_RESOURCE_RESTORE, getClass(),
-					LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry));
+					LoggingResourceable.wrap(entry, OlatResourceableType.genRepoEntry));
 		}
 		return Response.ok().build();
 	}
 	
+	@GET
+	@Path("access")
+	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response getAccess(@Context HttpServletRequest request) {
+		if(!isAuthor(request) && !isAuthorEditor(entry, request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		RepositoryEntryAccessVO accessVo = RepositoryEntryAccessVO.valueOf(entry);
+		return Response.ok(accessVo).build();
+	}
+	
+	@POST
+	@Path("access")
+	@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+	public Response updateAccess(RepositoryEntryAccessVO accessVo, @Context HttpServletRequest request) {
+		if(!isAuthor(request) && !isAuthorEditor(entry, request)) {
+			return Response.serverError().status(Status.UNAUTHORIZED).build();
+		}
+		if(accessVo.getRepoEntryKey() != null && !accessVo.getRepoEntryKey().equals(entry.getKey())) {
+			return Response.serverError().status(Status.BAD_REQUEST).build();
+		}
+		entry = repositoryManager.setAccess(entry, accessVo.getAccess(), accessVo.isMembersOnly());
+		return Response.ok(RepositoryEntryAccessVO.valueOf(entry)).build();
+	}
+	
 	private Response getIdentityInSecurityGroup(RepositoryEntry re, String role) {
 		List<Identity> identities = repositoryService.getMembers(re, role);
 		
@@ -883,29 +798,4 @@ public class RepositoryEntryWebService {
 		}
 		return Response.ok(ownerVOs).build();
 	}
-
-  private RepositoryEntry lookupRepositoryEntry(String key) {
-    Long repoEntryKey = longId(key);
-    RepositoryEntry re = null;
-    if(repoEntryKey != null) {//looks like a primary key
-      re = repositoryManager.lookupRepositoryEntry(repoEntryKey);
-    }
-    if(re == null) {// perhaps a soft key
-      re = repositoryManager.lookupRepositoryEntryBySoftkey(key, false);
-    }
-    return re;
-  }
-
-  private Long longId(String key) {
-    try {
-      for(int i=key.length(); i-->0; ) {
-        if(!Character.isDigit(key.charAt(i))) {
-          return null;
-        }
-      }
-      return new Long(key);
-    } catch(NumberFormatException ex) {
-      return null;
-    }
-  }
 }
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 bba33453a0d1d40eb63314400217d379af678168..33236ad7010e8d196f4333e607cd38d4a7dd901b 100644
--- a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java
@@ -116,11 +116,9 @@ public class CourseWebService {
 
 	private static final OLog log = Tracing.createLoggerFor(CourseWebService.class);
 	private static final XStream myXStream = XStreamHelper.createXStreamInstance();
-	
-	private static final String VERSION = "1.0";
+
 	
 	public static CacheControl cc = new CacheControl();
-
 	static {
 		cc.setMaxAge(-1);
 	}
@@ -132,20 +130,6 @@ public class CourseWebService {
 		this.course = course;
 		this.courseOres = courseOres;
 	}
-
-	/**
-	 * The version of the Course Web Service
-	 * @response.representation.200.mediaType text/plain
-	 * @response.representation.200.doc The version of this specific Web Service
-	 * @response.representation.200.example 1.0
-	 * @return
-	 */
-	@GET
-	@Path("version")
-	@Produces(MediaType.TEXT_PLAIN)
-	public Response getVersion() {
-		return Response.ok(VERSION).build();
-	}
 	
 	@Path("groups")
 	public CourseGroupWebService getCourseGroupWebService() {
diff --git a/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java b/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
index 5bff5a2c763df97959dc99a3fe7bafc5bf33e2b0..343d682eb241a3fd1794ed7984211ad55a8e6c68 100644
--- a/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
@@ -48,11 +48,11 @@ import javax.ws.rs.core.Request;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.olat.basesecurity.BaseSecurityManager;
+import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.OrganisationService;
 import org.olat.basesecurity.model.OrganisationRefImpl;
 import org.olat.core.CoreSpringFactory;
-import org.olat.core.commons.persistence.DBFactory;
+import org.olat.core.commons.persistence.DB;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
@@ -80,8 +80,6 @@ import org.olat.repository.handlers.RepositoryHandlerFactory;
 import org.olat.repository.model.SearchRepositoryEntryParameters;
 import org.olat.resource.OLATResource;
 import org.olat.resource.OLATResourceManager;
-import org.olat.resource.accesscontrol.ACService;
-import org.olat.resource.accesscontrol.AccessResult;
 import org.olat.restapi.security.RestSecurityHelper;
 import org.olat.restapi.support.MediaTypeVariants;
 import org.olat.restapi.support.MultipartReader;
@@ -89,6 +87,7 @@ import org.olat.restapi.support.ObjectFactory;
 import org.olat.restapi.support.vo.CourseConfigVO;
 import org.olat.restapi.support.vo.CourseVO;
 import org.olat.restapi.support.vo.CourseVOes;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 /**
@@ -107,6 +106,22 @@ public class CoursesWebService {
 	private static final OLog log = Tracing.createLoggerFor(CoursesWebService.class);
 
 	private static final String VERSION = "1.0";
+	
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private BaseSecurity securityManager;
+	@Autowired
+	private RepositoryManager repositoryManager;
+	@Autowired
+	private RepositoryService repositoryService;
+	@Autowired
+	private OrganisationService organisationService ;
+	@Autowired
+	private OLATResourceManager olatResourceManager;
+	@Autowired
+	private RepositoryHandlerFactory handlerFactory;
+
 
 	/**
 	 * The version of the Course Web Service
@@ -145,8 +160,6 @@ public class CoursesWebService {
 			@QueryParam("externalId") String externalId, @QueryParam("externalRef") String externalRef,
 			@QueryParam("repositoryEntryKey") String repositoryEntryKey,
 			@Context HttpServletRequest httpRequest, @Context Request request) {
-		RepositoryManager rm = RepositoryManager.getInstance();
-
 		Roles roles = getRoles(httpRequest);
 		Identity identity = getIdentity(httpRequest);
 		SearchRepositoryEntryParameters params = new SearchRepositoryEntryParameters(identity, roles, CourseModule.getCourseTypeName());
@@ -167,22 +180,22 @@ public class CoursesWebService {
 		}
 
 		if(MediaTypeVariants.isPaged(httpRequest, request)) {
-			int totalCount = rm.countGenericANDQueryWithRolesRestriction(params);
-			List<RepositoryEntry> repoEntries = rm.genericANDQueryWithRolesRestriction(params, start, limit, true);
+			int totalCount = repositoryManager.countGenericANDQueryWithRolesRestriction(params);
+			List<RepositoryEntry> repoEntries = repositoryManager.genericANDQueryWithRolesRestriction(params, start, limit, true);
 			CourseVO[] vos = toCourseVo(repoEntries);
 			CourseVOes voes = new CourseVOes();
 			voes.setCourses(vos);
 			voes.setTotalCount(totalCount);
 			return Response.ok(voes).build();
 		} else {
-			List<RepositoryEntry> repoEntries = rm.genericANDQueryWithRolesRestriction(params, 0, -1, false);
+			List<RepositoryEntry> repoEntries = repositoryManager.genericANDQueryWithRolesRestriction(params, 0, -1, false);
 			CourseVO[] vos = toCourseVo(repoEntries);
 			return Response.ok(vos).build();
 		}
 	}
 
-	public static CourseVO[] toCourseVo(List<RepositoryEntry> repoEntries) {
-		List<CourseVO> voList = new ArrayList<CourseVO>();
+	public CourseVO[] toCourseVo(List<RepositoryEntry> repoEntries) {
+		List<CourseVO> voList = new ArrayList<>();
 
 		int count=0;
 		for (RepositoryEntry repoEntry : repoEntries) {
@@ -190,7 +203,7 @@ public class CoursesWebService {
 				ICourse course = loadCourse(repoEntry.getOlatResource().getResourceableId());
 				voList.add(ObjectFactory.get(repoEntry, course));
 				if(count % 33 == 0) {
-					DBFactory.getInstance().commitAndCloseSession();
+					dbInstance.commitAndCloseSession();
 				}
 			} catch (Exception e) {
 				log.error("Cannot load the course with this repository entry: " + repoEntry, e);
@@ -210,7 +223,9 @@ public class CoursesWebService {
 			throw new WebApplicationException(Status.NOT_FOUND);
 		}
 		OLATResource ores = course.getCourseEnvironment().getCourseGroupManager().getCourseResource();
-		return new CourseWebService(ores, course);
+		CourseWebService ws = new CourseWebService(ores, course);
+		CoreSpringFactory.autowireObject(ws);
+		return ws;
 	}
 
 	/**
@@ -335,7 +350,7 @@ public class CoursesWebService {
 		Identity identity = null;
 		// Set the owner of the imported course to the user defined in the parameter
 		if (ownerUsername != null && !ownerUsername.isEmpty() && isAuthor(request)) {
-			identity = BaseSecurityManager.getInstance().findIdentityByName(ownerUsername);
+			identity = securityManager.findIdentityByName(ownerUsername);
 			if(identity == null) {
 				return Response.serverError().status(Status.BAD_REQUEST).build();
 			}
@@ -378,18 +393,6 @@ public class CoursesWebService {
 		return Response.ok(vo).build();
 	}
 
-	public static boolean isCourseAccessible(ICourse course, boolean authorRightsMandatory, HttpServletRequest request) {
-		if(authorRightsMandatory && !isAuthor(request)) {
-			return false;
-		}
-
-		Identity identity = getIdentity(request);
-		RepositoryEntry entry = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
-		ACService acManager = CoreSpringFactory.getImpl(ACService.class);
-		AccessResult result = acManager.isAccessible(entry, identity, false);
-		return result.isAccessible();
-	}
-
 	public static ICourse loadCourse(Long courseId) {
 		try {
 			return CourseFactory.loadCourse(courseId);
@@ -407,7 +410,6 @@ public class CoursesWebService {
 			displayName = "import-" + UUID.randomUUID().toString();
 		}
 		
-		OrganisationService organisationService = CoreSpringFactory.getImpl(OrganisationService.class);
 		Organisation organisation;
 		if(organisationKey == null) {
 			organisation = organisationService.getDefaultOrganisation();
@@ -415,7 +417,7 @@ public class CoursesWebService {
 			organisation = organisationService.getOrganisation(new OrganisationRefImpl(organisationKey));
 		}
 
-		RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(CourseModule.getCourseTypeName());
+		RepositoryHandler handler = handlerFactory.getRepositoryHandler(CourseModule.getCourseTypeName());
 		RepositoryEntry re = handler.importResource(identity, null, displayName, null, true, organisation, Locale.ENGLISH, fCourseImportZIP, null);
 
 		if(StringHelper.containsNonWhitespace(softKey)) {
@@ -444,17 +446,17 @@ public class CoursesWebService {
 			String managedFlags, CourseConfigVO courseConfigVO) {
 
 		OLATResourceable originalOresTrans = OresHelper.createOLATResourceableInstance(CourseModule.class, copyFrom);
-		RepositoryEntry src = RepositoryManager.getInstance().lookupRepositoryEntry(originalOresTrans, false);
+		RepositoryEntry src = repositoryManager.lookupRepositoryEntry(originalOresTrans, false);
 		if(src == null) {
-			src = RepositoryManager.getInstance().lookupRepositoryEntry(copyFrom, false);
+			src = repositoryManager.lookupRepositoryEntry(copyFrom, false);
 		}
 		if(src == null) {
 			log.warn("Cannot find course to copy from: " + copyFrom);
 			return null;
 		}
-		OLATResource originalOres = OLATResourceManager.getInstance().findResourceable(src.getOlatResource());
-		boolean isAlreadyLocked = RepositoryHandlerFactory.getInstance().getRepositoryHandler(src).isLocked(originalOres);
-		LockResult lockResult = RepositoryHandlerFactory.getInstance().getRepositoryHandler(src).acquireLock(originalOres, ureq.getIdentity());
+		OLATResource originalOres = olatResourceManager.findResourceable(src.getOlatResource());
+		boolean isAlreadyLocked = handlerFactory.getRepositoryHandler(src).isLocked(originalOres);
+		LockResult lockResult = handlerFactory.getRepositoryHandler(src).acquireLock(originalOres, ureq.getIdentity());
 
 		//check range of access
 		if(access < 1 || access > RepositoryEntry.ACC_USERS_GUESTS) {
@@ -462,9 +464,6 @@ public class CoursesWebService {
 		}
 
 		if(lockResult == null || (lockResult != null && lockResult.isSuccess()) && !isAlreadyLocked) {
-			RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class);
-			OrganisationService organisationService = CoreSpringFactory.getImpl(OrganisationService.class);
-
 			//create new repo entry
 			String name;
 			if(description == null || description.trim().length() == 0) {
@@ -490,11 +489,11 @@ public class CoursesWebService {
 			}
 
 			OLATResource sourceResource = src.getOlatResource();
-			OLATResource copyResource = OLATResourceManager.getInstance().createOLATResourceInstance(sourceResource.getResourceableTypeName());
+			OLATResource copyResource = olatResourceManager.createOLATResourceInstance(sourceResource.getResourceableTypeName());
 			RepositoryEntry preparedEntry = repositoryService.create(initialAuthor, null, resName, name,
 					description, copyResource, RepositoryEntry.ACC_OWNERS, organisation);
 
-			RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(src);
+			RepositoryHandler handler = handlerFactory.getRepositoryHandler(src);
 			preparedEntry = handler.copy(initialAuthor, src, preparedEntry);
 
 			preparedEntry.setCanDownload(src.getCanDownload());
@@ -527,10 +526,13 @@ public class CoursesWebService {
 			repositoryService.update(preparedEntry);
 
 			// copy image if available
-			RepositoryManager.getInstance().copyImage(src, preparedEntry);
+			repositoryManager.copyImage(src, preparedEntry);
+			
+			
+			
 
 			ICourse course = prepareCourse(preparedEntry,shortTitle, longTitle, courseConfigVO);
-			RepositoryHandlerFactory.getInstance().getRepositoryHandler(src).releaseLock(lockResult);
+			handlerFactory.getRepositoryHandler(src).releaseLock(lockResult);
 			return course;
 		}
 
@@ -558,10 +560,6 @@ public class CoursesWebService {
 		}
 
 		try {
-
-			RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class);
-			OrganisationService organisationService = CoreSpringFactory.getImpl(OrganisationService.class);
-			
 			Organisation organisation;
 			if(organisationKey == null) {
 				organisation = organisationService.getDefaultOrganisation();
@@ -570,7 +568,7 @@ public class CoursesWebService {
 			}
 
 			// create a repository entry
-			OLATResource resource = OLATResourceManager.getInstance().createOLATResourceInstance(CourseModule.class);
+			OLATResource resource = olatResourceManager.createOLATResourceInstance(CourseModule.class);
 			RepositoryEntry addedEntry = repositoryService.create(initialAuthor, null, "-", reDisplayName, null, resource, 0, organisation);
 			if(StringHelper.containsNonWhitespace(softKey) && softKey.length() <= 30) {
 				addedEntry.setSoftkey(softKey);
diff --git a/src/main/java/org/olat/restapi/support/vo/RepositoryEntryAccessVO.java b/src/main/java/org/olat/restapi/support/vo/RepositoryEntryAccessVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..e86f425951fab769f843919c4bcdddf1868fcc30
--- /dev/null
+++ b/src/main/java/org/olat/restapi/support/vo/RepositoryEntryAccessVO.java
@@ -0,0 +1,77 @@
+/**
+ * <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.restapi.support.vo;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.olat.repository.RepositoryEntry;
+
+/**
+ * 
+ * Initial date: 14 juin 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "repositoryEntryAccessVO")
+public class RepositoryEntryAccessVO {
+
+	private Long repoEntryKey;
+	private int access;
+	private boolean membersOnly;
+	
+	public RepositoryEntryAccessVO() {
+		//
+	}
+	
+	public static RepositoryEntryAccessVO valueOf(RepositoryEntry entry) {
+		RepositoryEntryAccessVO accessVo = new RepositoryEntryAccessVO();
+		accessVo.setRepoEntryKey(entry.getKey());
+		accessVo.setAccess(entry.getAccess());
+		accessVo.setMembersOnly(entry.isMembersOnly());
+		return accessVo;
+	}
+
+	public Long getRepoEntryKey() {
+		return repoEntryKey;
+	}
+
+	public void setRepoEntryKey(Long repoEntryKey) {
+		this.repoEntryKey = repoEntryKey;
+	}
+
+	public int getAccess() {
+		return access;
+	}
+
+	public void setAccess(int access) {
+		this.access = access;
+	}
+
+	public boolean isMembersOnly() {
+		return membersOnly;
+	}
+
+	public void setMembersOnly(boolean membersOnly) {
+		this.membersOnly = membersOnly;
+	}
+}
diff --git a/src/main/java/org/olat/user/restapi/OrganisationsWebService.java b/src/main/java/org/olat/user/restapi/OrganisationsWebService.java
index df70403a2ad63f8d09c1d3c8d7bc8aa8c6dd124e..15a310d44219f5ea6414a74f42cba66f1b9a6e03 100644
--- a/src/main/java/org/olat/user/restapi/OrganisationsWebService.java
+++ b/src/main/java/org/olat/user/restapi/OrganisationsWebService.java
@@ -33,12 +33,14 @@ 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.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.basesecurity.GroupMembershipInheritance;
 import org.olat.basesecurity.OrganisationManagedFlag;
 import org.olat.basesecurity.OrganisationRoles;
 import org.olat.basesecurity.OrganisationService;
@@ -332,15 +334,16 @@ public class OrganisationsWebService {
 	@PUT
 	@Path("{organisationKey}/{role}/{identityKey}")
 	public Response putMember(@PathParam("organisationKey") Long organisationKey, @PathParam("role") String role,
-			@PathParam("identityKey") Long identityKey, @Context HttpServletRequest httpRequest) {
+			@PathParam("identityKey") Long identityKey, @QueryParam("inheritanceMode") String inheritanceMode,
+			@Context HttpServletRequest httpRequest) {
 		boolean isSystemAdministrator = isAdmin(httpRequest);
 		if(!isSystemAdministrator) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
-		return putMember(organisationKey, identityKey, getRoles(role));
+		return putMember(organisationKey, identityKey, getRoles(role), inheritanceMode);
 	}
 	
-	private Response putMember(Long organisationKey, Long identityKey, OrganisationRoles role) {
+	private Response putMember(Long organisationKey, Long identityKey, OrganisationRoles role, String inheritanceMode) {
 		Organisation organisation = organisationService.getOrganisation(new OrganisationRefImpl(organisationKey));
 		if(organisation == null) {
 			return Response.serverError().status(Status.NOT_FOUND).build();
@@ -353,7 +356,12 @@ public class OrganisationsWebService {
 		if(identity == null) {
 			return Response.serverError().status(Status.NOT_FOUND).build();
 		}
-		organisationService.addMember(organisation, identity, role);
+		
+		if(GroupMembershipInheritance.isValueOf(inheritanceMode)) {
+			organisationService.addMember(organisation, identity, role, GroupMembershipInheritance.valueOf(inheritanceMode));
+		} else {
+			organisationService.addMember(organisation, identity, role);
+		}
 		return Response.ok().build();
 	}
 	
@@ -375,7 +383,8 @@ public class OrganisationsWebService {
 	@PUT
 	@Path("{organisationKey}/{role}")
 	public Response putMembers(@PathParam("organisationKey") Long organisationKey, @PathParam("role") String role,
-			UserVO[] members, @Context HttpServletRequest httpRequest) {
+			@QueryParam("inheritanceMode") String inheritanceMode, UserVO[] members,
+			@Context HttpServletRequest httpRequest) {
 		boolean isSystemAdministrator = isAdmin(httpRequest);
 		if(!isSystemAdministrator) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
@@ -388,11 +397,20 @@ public class OrganisationsWebService {
 		if(getRoles(role) == null) {
 			return Response.serverError().status(Status.CONFLICT).build();
 		}
+		
+		GroupMembershipInheritance inheritance = null;
+		if(GroupMembershipInheritance.isValueOf(inheritanceMode)) {
+			inheritance = GroupMembershipInheritance.valueOf(inheritanceMode);
+		}
 
 		for(UserVO member:members) {
 			Identity identity = securityManager.loadIdentityByKey(member.getKey());
 			if(identity != null) {
-				organisationService.addMember(organisation, identity, getRoles(role));
+				if(inheritance == null) {
+					organisationService.addMember(organisation, identity, getRoles(role));
+				} else {
+					organisationService.addMember(organisation, identity, getRoles(role), inheritance);
+				}
 			}
 		}
 		return Response.ok().build();
diff --git a/src/main/java/org/olat/user/restapi/UserCoursesWebService.java b/src/main/java/org/olat/user/restapi/UserCoursesWebService.java
index 95ae4397ba780742b1a7e5f9d19eae3d6aede3a0..8dd9ebf097845879ace8e147cdb147a1d960d02b 100644
--- a/src/main/java/org/olat/user/restapi/UserCoursesWebService.java
+++ b/src/main/java/org/olat/user/restapi/UserCoursesWebService.java
@@ -19,6 +19,7 @@
  */
 package org.olat.user.restapi;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -33,14 +34,20 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Request;
 import javax.ws.rs.core.Response;
 
+import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.course.ICourse;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryOrder;
 import org.olat.repository.RepositoryManager;
 import org.olat.restapi.repository.course.CoursesWebService;
 import org.olat.restapi.support.MediaTypeVariants;
+import org.olat.restapi.support.ObjectFactory;
 import org.olat.restapi.support.vo.CourseVO;
 import org.olat.restapi.support.vo.CourseVOes;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
@@ -49,13 +56,19 @@ import org.olat.restapi.support.vo.CourseVOes;
  */
 public class UserCoursesWebService {
 	
+	private static final OLog log = Tracing.createLoggerFor(UserCoursesWebService.class);
+	
 	private final Identity identity;
 	
+	@Autowired
+	private DB dbInstance;
+	@Autowired
+	private RepositoryManager repositoryManager;
+	
 	public UserCoursesWebService(Identity identity) {
 		this.identity = identity;
 	}
 	
-	
 	/**
 	 * Retrieves the list of "My entries" but limited to courses.
 	 * @response.representation.200.qname {http://www.example.com}courseVO
@@ -76,10 +89,9 @@ public class UserCoursesWebService {
 			@QueryParam("limit") @DefaultValue("25") Integer limit, @Context HttpServletRequest httpRequest,
 			@Context Request request) {
 		
-		RepositoryManager rm = RepositoryManager.getInstance();
 		if(MediaTypeVariants.isPaged(httpRequest, request)) {
-			List<RepositoryEntry> repoEntries = rm.getLearningResourcesAsStudent(identity, null, start, limit, RepositoryEntryOrder.nameAsc);
-			int totalCount= rm.countLearningResourcesAsStudent(identity);
+			List<RepositoryEntry> repoEntries = repositoryManager.getLearningResourcesAsStudent(identity, null, start, limit, RepositoryEntryOrder.nameAsc);
+			int totalCount= repositoryManager.countLearningResourcesAsStudent(identity);
 
 			CourseVO[] vos = toCourseVo(repoEntries);
 			CourseVOes voes = new CourseVOes();
@@ -87,7 +99,7 @@ public class UserCoursesWebService {
 			voes.setTotalCount(totalCount);
 			return Response.ok(voes).build();
 		} else {
-			List<RepositoryEntry> repoEntries = rm.getLearningResourcesAsStudent(identity, null, 0, -1, RepositoryEntryOrder.nameAsc);
+			List<RepositoryEntry> repoEntries = repositoryManager.getLearningResourcesAsStudent(identity, null, 0, -1, RepositoryEntryOrder.nameAsc);
 			CourseVO[] vos = toCourseVo(repoEntries);
 			return Response.ok(vos).build();
 		}
@@ -113,10 +125,9 @@ public class UserCoursesWebService {
 			@QueryParam("limit") @DefaultValue("25") Integer limit, @Context HttpServletRequest httpRequest,
 			@Context Request request) {
 		
-		RepositoryManager rm = RepositoryManager.getInstance();
 		if(MediaTypeVariants.isPaged(httpRequest, request)) {
-			List<RepositoryEntry> repoEntries = rm.getLearningResourcesAsTeacher(identity, start, limit, RepositoryEntryOrder.nameAsc);
-			int totalCount= rm.countLearningResourcesAsTeacher(identity);
+			List<RepositoryEntry> repoEntries = repositoryManager.getLearningResourcesAsTeacher(identity, start, limit, RepositoryEntryOrder.nameAsc);
+			int totalCount= repositoryManager.countLearningResourcesAsTeacher(identity);
 
 			CourseVO[] vos = toCourseVo(repoEntries);
 			CourseVOes voes = new CourseVOes();
@@ -124,7 +135,7 @@ public class UserCoursesWebService {
 			voes.setTotalCount(totalCount);
 			return Response.ok(voes).build();
 		} else {
-			List<RepositoryEntry> repoEntries = rm.getLearningResourcesAsTeacher(identity, 0, -1);
+			List<RepositoryEntry> repoEntries = repositoryManager.getLearningResourcesAsTeacher(identity, 0, -1);
 			CourseVO[] vos = toCourseVo(repoEntries);
 			return Response.ok(vos).build();
 		}
@@ -151,15 +162,14 @@ public class UserCoursesWebService {
 			@Context Request request) {
 		
 		List<String> courseType = Collections.singletonList("CourseModule");
-		RepositoryManager rm = RepositoryManager.getInstance();
 		if(MediaTypeVariants.isPaged(httpRequest, request)) {
-			List<RepositoryEntry> repoEntries = rm.getFavoritLearningResourcesAsTeacher(identity, courseType, start, limit, RepositoryEntryOrder.nameAsc);
+			List<RepositoryEntry> repoEntries = repositoryManager.getFavoritLearningResourcesAsTeacher(identity, courseType, start, limit, RepositoryEntryOrder.nameAsc);
 			
 			int totalCount;
 			if(repoEntries.size() < limit) {
 				totalCount = repoEntries.size();
 			} else {
-				totalCount = rm.countFavoritLearningResourcesAsTeacher(identity, courseType);
+				totalCount = repositoryManager.countFavoritLearningResourcesAsTeacher(identity, courseType);
 			}
 			CourseVO[] vos = toCourseVo(repoEntries);
 			CourseVOes voes = new CourseVOes();
@@ -167,13 +177,29 @@ public class UserCoursesWebService {
 			voes.setTotalCount(totalCount);
 			return Response.ok(voes).build();
 		} else {
-			List<RepositoryEntry> repoEntries = rm.getFavoritLearningResourcesAsTeacher(identity, courseType, 0, -1, RepositoryEntryOrder.nameAsc);
+			List<RepositoryEntry> repoEntries = repositoryManager.getFavoritLearningResourcesAsTeacher(identity, courseType, 0, -1, RepositoryEntryOrder.nameAsc);
 			CourseVO[] vos = toCourseVo(repoEntries);
 			return Response.ok(vos).build();
 		}
 	}
 	
 	private CourseVO[] toCourseVo(List<RepositoryEntry> repoEntries) {
-		return CoursesWebService.toCourseVo(repoEntries);
+		List<CourseVO> voList = new ArrayList<>(repoEntries.size());
+
+		int count=0;
+		for (RepositoryEntry repoEntry : repoEntries) {
+			try {
+				ICourse course = CoursesWebService.loadCourse(repoEntry.getOlatResource().getResourceableId());
+				if(course != null) {
+					voList.add(ObjectFactory.get(repoEntry, course));
+				}
+				if(count % 33 == 0) {
+					dbInstance.commitAndCloseSession();
+				}
+			} catch (Exception e) {
+				log.error("Cannot load the course with this repository entry: " + repoEntry, e);
+			}
+		}
+		return voList.toArray(new CourseVO[voList.size()]);
 	}
 }
diff --git a/src/main/java/org/olat/user/restapi/UserWebService.java b/src/main/java/org/olat/user/restapi/UserWebService.java
index bd447782c69d309df66a42f2247fa81bffb0955b..cf8e2b51f16c356d7d9779e789013d6b81196ef5 100644
--- a/src/main/java/org/olat/user/restapi/UserWebService.java
+++ b/src/main/java/org/olat/user/restapi/UserWebService.java
@@ -542,7 +542,9 @@ public class UserWebService {
 		if(ureqIdentity == null || !ureqIdentity.equals(identity)) {
 			throw new WebApplicationException(Response.serverError().status(Status.UNAUTHORIZED).build());
 		}
-		return new UserCoursesWebService(identity);
+		UserCoursesWebService ws = new UserCoursesWebService(identity);
+		CoreSpringFactory.autowireObject(ws);
+		return ws;
 	}
 	
 	/**
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
index 99c7669571ac8611c5274c67dae6f363da6cc3d7..f2cc85e56ce7790c3fa853c3fb354ce10915c4cb 100644
--- a/src/main/resources/META-INF/persistence.xml
+++ b/src/main/resources/META-INF/persistence.xml
@@ -157,7 +157,6 @@
 		<class>org.olat.modules.curriculum.model.CurriculumElementImpl</class>
 		<class>org.olat.modules.curriculum.model.CurriculumElementTypeImpl</class>
 		<class>org.olat.modules.curriculum.model.CurriculumElementTypeToTypeImpl</class>
-		<class>org.olat.modules.curriculum.model.CurriculumRepositoryEntryRelationImpl</class>
 		<class>org.olat.modules.fo.model.ForumImpl</class>
 		<class>org.olat.modules.fo.model.MessageImpl</class>
 		<class>org.olat.modules.fo.model.MessageRefImpl</class>
diff --git a/src/main/resources/database/mysql/alter_12_4_x_to_13_0_0.sql b/src/main/resources/database/mysql/alter_12_4_x_to_13_0_0.sql
index 194e056402b802ac5203fe990e985f52df35f45c..5ab1f096d056149bd82f337db2998b666908a62f 100644
--- a/src/main/resources/database/mysql/alter_12_4_x_to_13_0_0.sql
+++ b/src/main/resources/database/mysql/alter_12_4_x_to_13_0_0.sql
@@ -140,20 +140,6 @@ alter table o_cur_element_type_to_type ENGINE = InnoDB;
 alter table o_cur_element_type_to_type add constraint cur_type_to_type_idx foreign key (fk_type) references o_cur_element_type (id);
 alter table o_cur_element_type_to_type add constraint cur_type_to_sub_type_idx foreign key (fk_allowed_sub_type) references o_cur_element_type (id);
 
-create table o_re_to_curriculum_element (
-  id bigint not null auto_increment,
-  creationdate datetime not null,
-  lastmodified datetime not null,
-  c_master bit default 0,
-  fk_entry bigint not null,
-  fk_curriculum_element bigint not null,
-  primary key (id)
-);
-alter table o_re_to_curriculum_element ENGINE = InnoDB;
-
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_re_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id);
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_cur_el_idx foreign key (fk_curriculum_element) references o_cur_curriculum_element (id);
-
 
 -- drop policy
 alter table o_bs_policy drop foreign key FK9A1C5101E2E76DB;
diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql
index 68fee844cab0df24eb9d12ec3721fddd94427977..2cf866fa4879ca0f913f0de30453345eb1a45015 100644
--- a/src/main/resources/database/mysql/setupDatabase.sql
+++ b/src/main/resources/database/mysql/setupDatabase.sql
@@ -2438,15 +2438,6 @@ create table o_cur_element_type_to_type (
   primary key (id)
 );
 
-create table o_re_to_curriculum_element (
-  id bigint not null auto_increment,
-  creationdate datetime not null,
-  lastmodified datetime not null,
-  c_master bit default 0,
-  fk_entry bigint not null,
-  fk_curriculum_element bigint not null,
-  primary key (id)
-);
 
 -- user view
 create view o_bs_identity_short_v as (
@@ -2814,7 +2805,6 @@ alter table o_cur_element_type ENGINE = InnoDB;
 alter table o_cur_curriculum ENGINE = InnoDB;
 alter table o_cur_curriculum_element ENGINE = InnoDB;
 alter table o_cur_element_type_to_type ENGINE = InnoDB;
-alter table o_re_to_curriculum_element ENGINE = InnoDB;	
 
 -- rating
 alter table o_userrating add constraint FKF26C8375236F20X foreign key (creator_id) references o_bs_identity (id);
@@ -3394,9 +3384,6 @@ alter table o_cur_curriculum_element add constraint cur_el_type_to_el_type_idx f
 alter table o_cur_element_type_to_type add constraint cur_type_to_type_idx foreign key (fk_type) references o_cur_element_type (id);
 alter table o_cur_element_type_to_type add constraint cur_type_to_sub_type_idx foreign key (fk_allowed_sub_type) references o_cur_element_type (id);
 
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_re_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id);
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_cur_el_idx foreign key (fk_curriculum_element) references o_cur_curriculum_element (id);
-
 
 -- o_logging_table
 create index log_target_resid_idx on o_loggingtable(targetresid);
diff --git a/src/main/resources/database/oracle/alter_12_4_x_to_13_0_0.sql b/src/main/resources/database/oracle/alter_12_4_x_to_13_0_0.sql
index ff53939df20ceb65212a2a8b6ca030c50bb26abd..7b70ecdc8c942fbf42973c2fa11615a2379e327f 100644
--- a/src/main/resources/database/oracle/alter_12_4_x_to_13_0_0.sql
+++ b/src/main/resources/database/oracle/alter_12_4_x_to_13_0_0.sql
@@ -146,21 +146,6 @@ create index idx_cur_type_to_type_idx on o_cur_element_type_to_type (fk_type);
 alter table o_cur_element_type_to_type add constraint cur_type_to_sub_type_idx foreign key (fk_allowed_sub_type) references o_cur_element_type (id);
 create index idx_cur_type_to_sub_type_idx on o_cur_element_type_to_type (fk_allowed_sub_type);
 
-create table o_re_to_curriculum_element (
-  id number(20) generated always as identity,
-  creationdate date not null,
-  lastmodified date not null,
-  c_master number default 0,
-  fk_entry number(20) not null,
-  fk_curriculum_element number(20) not null,
-  primary key (id)
-);
-
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_re_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id);
-create index idx_rel_cur_el_to_re_idx on o_re_to_curriculum_element (fk_entry);
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_cur_el_idx foreign key (fk_curriculum_element) references o_cur_curriculum_element (id);
-create index idx_rel_cur_el_to_cur_el_idx on o_re_to_curriculum_element (fk_curriculum_element);
-
 
 -- evaluation forms
 create table o_eva_form_survey (
diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql
index 430e83585918a3206bee37366b4376124437795b..3ac9cf89341dfcd230ab4ecc724759cc71c5b3a0 100644
--- a/src/main/resources/database/oracle/setupDatabase.sql
+++ b/src/main/resources/database/oracle/setupDatabase.sql
@@ -2514,15 +2514,6 @@ create table o_cur_element_type_to_type (
   primary key (id)
 );
 
-create table o_re_to_curriculum_element (
-  id number(20) generated always as identity,
-  creationdate date not null,
-  lastmodified date not null,
-  c_master number default 0,
-  fk_entry number(20) not null,
-  fk_curriculum_element number(20) not null,
-  primary key (id)
-);
 
 -- user view
 create view o_bs_identity_short_v as (
@@ -3580,11 +3571,6 @@ create index idx_cur_type_to_type_idx on o_cur_element_type_to_type (fk_type);
 alter table o_cur_element_type_to_type add constraint cur_type_to_sub_type_idx foreign key (fk_allowed_sub_type) references o_cur_element_type (id);
 create index idx_cur_type_to_sub_type_idx on o_cur_element_type_to_type (fk_allowed_sub_type);
 
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_re_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id);
-create index idx_rel_cur_el_to_re_idx on o_re_to_curriculum_element (fk_entry);
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_cur_el_idx foreign key (fk_curriculum_element) references o_cur_curriculum_element (id);
-create index idx_rel_cur_el_to_cur_el_idx on o_re_to_curriculum_element (fk_curriculum_element);
-
 -- o_logging_table
 create index log_target_resid_idx on o_loggingtable(targetresid);
 create index log_ptarget_resid_idx on o_loggingtable(parentresid);
diff --git a/src/main/resources/database/postgresql/alter_12_4_x_to_13_0_0.sql b/src/main/resources/database/postgresql/alter_12_4_x_to_13_0_0.sql
index b75f419247148adf51eadfbc09beecfc6a2825a7..379a80fbf810c0616f1b2dc2367be6f6088f86ae 100644
--- a/src/main/resources/database/postgresql/alter_12_4_x_to_13_0_0.sql
+++ b/src/main/resources/database/postgresql/alter_12_4_x_to_13_0_0.sql
@@ -147,21 +147,6 @@ create index idx_cur_type_to_type_idx on o_cur_element_type_to_type (fk_type);
 alter table o_cur_element_type_to_type add constraint cur_type_to_sub_type_idx foreign key (fk_allowed_sub_type) references o_cur_element_type (id);
 create index idx_cur_type_to_sub_type_idx on o_cur_element_type_to_type (fk_allowed_sub_type);
 
-create table o_re_to_curriculum_element (
-  id bigserial,
-  creationdate timestamp not null,
-  lastmodified timestamp not null,
-  c_master bool default false,
-  fk_entry int8 not null,
-  fk_curriculum_element int8 not null,
-  primary key (id)
-);
-
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_re_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id);
-create index idx_rel_cur_el_to_re_idx on o_re_to_curriculum_element (fk_entry);
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_cur_el_idx foreign key (fk_curriculum_element) references o_cur_curriculum_element (id);
-create index idx_rel_cur_el_to_cur_el_idx on o_re_to_curriculum_element (fk_curriculum_element);
-
 
 -- drop policy
 alter table o_bs_policy drop constraint FK9A1C5101E2E76DB;
diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql
index a6acd135a218412df4d12f4da5aa634a07be9abc..ae96aa221215c425347d30d2147e4604a41f77a0 100644
--- a/src/main/resources/database/postgresql/setupDatabase.sql
+++ b/src/main/resources/database/postgresql/setupDatabase.sql
@@ -2464,16 +2464,6 @@ create table o_cur_element_type_to_type (
   primary key (id)
 );
 
-create table o_re_to_curriculum_element (
-  id bigserial,
-  creationdate timestamp not null,
-  lastmodified timestamp not null,
-  c_master bool default false,
-  fk_entry int8 not null,
-  fk_curriculum_element int8 not null,
-  primary key (id)
-);
-
 -- user view
 create view o_bs_identity_short_v as (
    select
@@ -3482,11 +3472,6 @@ create index idx_cur_type_to_type_idx on o_cur_element_type_to_type (fk_type);
 alter table o_cur_element_type_to_type add constraint cur_type_to_sub_type_idx foreign key (fk_allowed_sub_type) references o_cur_element_type (id);
 create index idx_cur_type_to_sub_type_idx on o_cur_element_type_to_type (fk_allowed_sub_type);
 
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_re_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id);
-create index idx_rel_cur_el_to_re_idx on o_re_to_curriculum_element (fk_entry);
-alter table o_re_to_curriculum_element add constraint rel_cur_el_to_cur_el_idx foreign key (fk_curriculum_element) references o_cur_curriculum_element (id);
-create index idx_rel_cur_el_to_cur_el_idx on o_re_to_curriculum_element (fk_curriculum_element);
-
 -- o_logging_table
 create index log_target_resid_idx on o_loggingtable(targetresid);
 create index log_ptarget_resid_idx on o_loggingtable(parentresid);
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 e1355c80ddcbf1247a707d4734f2156338abe9db..bccbfe1f77477b50393729f870ef7b7f9405532c 100644
--- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
+++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
@@ -27,7 +27,6 @@ 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.CurriculumRepositoryEntryRelation;
 import org.olat.modules.curriculum.CurriculumService;
 import org.olat.repository.RepositoryEntry;
 import org.olat.test.JunitTestHelper;
@@ -49,25 +48,6 @@ public class CurriculumRepositoryEntryRelationDAOTest extends OlatTestCase {
 	@Autowired
 	private CurriculumRepositoryEntryRelationDAO curriculumRepositoryEntryRelationDao;
 	
-	@Test
-	public void createRelation() {
-		Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-1", "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.commitAndCloseSession();
-		
-		CurriculumRepositoryEntryRelation relation = curriculumRepositoryEntryRelationDao.createRelation(entry, element, true);
-		dbInstance.commit();
-		Assert.assertNotNull(relation);
-		Assert.assertNotNull(relation.getKey());
-		Assert.assertNotNull(relation.getCreationDate());
-		Assert.assertNotNull(relation.getLastModified());
-		Assert.assertEquals(element, relation.getCurriculumElement());
-		Assert.assertEquals(entry, relation.getEntry());
-		Assert.assertTrue(relation.isMaster());
-	}
-	
 	@Test
 	public void getRepositoryEntries() {
 		Curriculum curriculum = curriculumService.createCurriculum("cur-el-rel-2", "Curriculum for relation", "Curriculum", null);
@@ -99,44 +79,4 @@ public class CurriculumRepositoryEntryRelationDAOTest extends OlatTestCase {
 		Assert.assertEquals(1, elements.size());
 		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/restapi/LecturesBlocksTest.java b/src/test/java/org/olat/restapi/LecturesBlocksTest.java
index b854ed88fe8c692b13d77318a9de5caa52e7abef..a8d072d5384cf172c470064289261390fd41eeaa 100644
--- a/src/test/java/org/olat/restapi/LecturesBlocksTest.java
+++ b/src/test/java/org/olat/restapi/LecturesBlocksTest.java
@@ -501,6 +501,48 @@ public class LecturesBlocksTest extends OlatJerseyTestCase {
 		Assert.assertTrue(teachers.contains(teacher2));
 	}
 	
+	/**
+	 * Move a lecture block from one course to the other.
+	 * 
+	 * @throws IOException
+	 * @throws URISyntaxException
+	 */
+	@Test
+	public void moveLectureBlock()
+	throws IOException, URISyntaxException {
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("lect-1");
+		RepositoryEntry entryOrigin = JunitTestHelper.deployBasicCourse(author);
+		RepositoryEntry entryTarget = JunitTestHelper.deployBasicCourse(author);
+		ICourse courseOrigin = CourseFactory.loadCourse(entryOrigin);
+		entryOrigin = courseOrigin.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		LectureBlock block = createLectureBlock(entryOrigin);
+		dbInstance.commit();
+
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+
+		URI uri = UriBuilder.fromUri(getContextURI()).path("repo").path("courses").path(courseOrigin.getResourceableId().toString())
+				.path("lectureblocks").path(block.getKey().toString())
+				.path("entry").path(entryTarget.getKey().toString()).build();
+		HttpPost method = conn.createPost(uri, MediaType.APPLICATION_JSON);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		LectureBlockVO movedBlock = conn.parse(response, LectureBlockVO.class);
+		Assert.assertNotNull(movedBlock);
+		Assert.assertEquals(entryTarget.getKey(), movedBlock.getRepoEntryKey());
+		
+		// check lecture blocks of origin
+		List<LectureBlock> originBlocks = lectureService.getLectureBlocks(entryOrigin);
+		Assert.assertNotNull(originBlocks);
+		Assert.assertTrue(originBlocks.isEmpty());
+		
+		// check lecture block of target
+		List<LectureBlock> targetBlocks = lectureService.getLectureBlocks(entryTarget);
+		Assert.assertNotNull(targetBlocks);
+		Assert.assertEquals(1, targetBlocks.size());
+		Assert.assertEquals(block.getKey(), targetBlocks.get(0).getKey());		
+	}
+	
 	private LectureBlock createLectureBlock(RepositoryEntry entry) {
 		LectureBlock lectureBlock = lectureService.createLectureBlock(entry);
 		lectureBlock.setStartDate(new Date());
diff --git a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
index 6d00923302916e8b52e6153cb60954d55d3b27aa..e183deeb107ff8a811df1b0c115bc3cb1f301f17 100644
--- a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
+++ b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
@@ -72,6 +72,7 @@ import org.olat.repository.RepositoryService;
 import org.olat.resource.OLATResource;
 import org.olat.resource.OLATResourceManager;
 import org.olat.restapi.support.ObjectFactory;
+import org.olat.restapi.support.vo.RepositoryEntryAccessVO;
 import org.olat.restapi.support.vo.RepositoryEntryLifecycleVO;
 import org.olat.restapi.support.vo.RepositoryEntryVO;
 import org.olat.restapi.support.vo.RepositoryEntryVOes;
@@ -819,6 +820,65 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 		Assert.assertTrue(participants.isEmpty());
 		Assert.assertFalse(participants.contains(participant));
 	}
+	
+	@Test
+	public void getAccess() throws IOException, URISyntaxException {
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
+		dbInstance.commitAndCloseSession();
+
+		//remove the owner
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		URI request = UriBuilder.fromUri(getContextURI())
+				.path("repo/entries").path(re.getKey().toString()).path("access").build();
+		HttpGet method = conn.createGet(request, MediaType.APPLICATION_JSON, true);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		RepositoryEntryAccessVO accessVo = conn.parse(response, RepositoryEntryAccessVO.class);
+		conn.shutdown();
+		
+		//check
+		Assert.assertNotNull(accessVo);
+		Assert.assertEquals(re.getKey(), accessVo.getRepoEntryKey());
+		Assert.assertEquals(re.getAccess(), accessVo.getAccess());
+		Assert.assertEquals(re.isMembersOnly(), accessVo.isMembersOnly());
+	}
+	
+	@Test
+	public void updateAccess() throws IOException, URISyntaxException {
+		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry(false);
+		dbInstance.commitAndCloseSession();
+		Assert.assertFalse(re.isMembersOnly());
+
+		//remove the owner
+		RestConnection conn = new RestConnection();
+		assertTrue(conn.login("administrator", "openolat"));
+		
+		RepositoryEntryAccessVO accessVo = new RepositoryEntryAccessVO();
+		accessVo.setAccess(RepositoryEntry.ACC_OWNERS);
+		accessVo.setMembersOnly(true);
+		
+		URI request = UriBuilder.fromUri(getContextURI())
+				.path("repo/entries").path(re.getKey().toString()).path("access").build();
+		HttpPost method = conn.createPost(request, MediaType.APPLICATION_JSON);
+		conn.addJsonEntity(method, accessVo);
+		HttpResponse response = conn.execute(method);
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		RepositoryEntryAccessVO updatedAccessVo = conn.parse(response, RepositoryEntryAccessVO.class);
+		conn.shutdown();
+		
+		// check return value
+		Assert.assertNotNull(updatedAccessVo);
+		Assert.assertEquals(re.getKey(), updatedAccessVo.getRepoEntryKey());
+		Assert.assertEquals(RepositoryEntry.ACC_OWNERS, updatedAccessVo.getAccess());
+		Assert.assertEquals(true, updatedAccessVo.isMembersOnly());
+		
+		// check database value
+		RepositoryEntry updatedRe = repositoryService.loadByKey(re.getKey());
+		Assert.assertEquals(RepositoryEntry.ACC_OWNERS, updatedRe.getAccess());
+		Assert.assertEquals(true, updatedRe.isMembersOnly());
+	}
 
 	private List<RepositoryEntryVO> parseRepoArray(HttpEntity entity) {
 		try(InputStream in=entity.getContent()) {