diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java
index be58679480fb50d2a581d6e357fb93ce6d74beaf..55fd8a63e203fcd2e32d76ac006ca848de2bde4e 100644
--- a/src/main/java/org/olat/course/CourseFactory.java
+++ b/src/main/java/org/olat/course/CourseFactory.java
@@ -131,6 +131,7 @@ import org.olat.repository.handlers.RepositoryHandler;
 import org.olat.repository.handlers.RepositoryHandlerFactory;
 import org.olat.repository.model.RepositoryEntrySecurity;
 import org.olat.resource.OLATResource;
+import org.olat.resource.OLATResourceManager;
 import org.olat.resource.references.Reference;
 import org.olat.resource.references.ReferenceManager;
 import org.olat.user.UserManager;
@@ -216,7 +217,7 @@ public class CourseFactory extends BasicManager {
 	public static ICourse createCourse(RepositoryEntry courseEntry,
 			String shortTitle, String longTitle, String learningObjectives) {
 		OLATResource courseResource = courseEntry.getOlatResource();
-		PersistingCourseImpl newCourse = new PersistingCourseImpl(courseResource.getResourceableId());
+		PersistingCourseImpl newCourse = new PersistingCourseImpl(courseResource);
 		// Put new course in course cache    
 		loadedCourses.put(newCourse.getResourceableId(), newCourse);
 		
@@ -284,7 +285,8 @@ public class CourseFactory extends BasicManager {
 		if (course == null) {
 			// o_clusterOK by:ld - load and put in cache in doInSync block to ensure
 			// that no invalidate cache event was missed
-			PersistingCourseImpl theCourse = new PersistingCourseImpl(resourceableId);
+			OLATResource resource = OLATResourceManager.getInstance().findResourceable(resourceableId, "CourseModule");
+			PersistingCourseImpl theCourse = new PersistingCourseImpl(resource);
 			theCourse.load();
 			
 			PersistingCourseImpl cachedCourse = loadedCourses.putIfAbsent(resourceableId, theCourse);
@@ -357,7 +359,7 @@ public class CourseFactory extends BasicManager {
 		// delete all course notifications
 		NotificationsManager.getInstance().deletePublishersOf(res);
 		//delete calendar subscription
-		clearCalenderSubscriptions(res);
+		clearCalenderSubscriptions(res, course);
 		// delete course configuration (not really usefull, the config is in
 		// the course folder which is deleted right after)
 		if(course != null) {
@@ -399,20 +401,23 @@ public class CourseFactory extends BasicManager {
 	 * Checks all learning group calendars and the course calendar for publishers (of subscriptions)
 	 * and sets their state to "1" which indicates that the ressource is deleted.
 	 */
-	private static void clearCalenderSubscriptions(OLATResourceable res) {
+	private static void clearCalenderSubscriptions(OLATResourceable res, ICourse course) {
 		//set Publisher state to 1 (= ressource is deleted) for all calendars of the course
 		CalendarManager calMan = CoreSpringFactory.getImpl(CalendarManager.class);
 		CalendarNotificationManager notificationManager = CoreSpringFactory.getImpl(CalendarNotificationManager.class);
 		NotificationsManager nfm = NotificationsManager.getInstance();
-		CourseGroupManager courseGroupManager = PersistingCourseGroupManager.getInstance(res);
-		List<BusinessGroup> learningGroups = courseGroupManager.getAllBusinessGroups();
-		//all learning and right group calendars
-		for (BusinessGroup bg : learningGroups) {
-			KalendarRenderWrapper calRenderWrapper = calMan.getGroupCalendar(bg);
-			SubscriptionContext subsContext = notificationManager.getSubscriptionContext(calRenderWrapper);
-			Publisher pub = nfm.getPublisher(subsContext);
-			if (pub != null) {
-				pub.setState(1); //int 0 is OK -> all other is not OK
+		
+		if(course != null) {
+			CourseGroupManager courseGroupManager = course.getCourseEnvironment().getCourseGroupManager();
+			List<BusinessGroup> learningGroups = courseGroupManager.getAllBusinessGroups();
+			//all learning and right group calendars
+			for (BusinessGroup bg : learningGroups) {
+				KalendarRenderWrapper calRenderWrapper = calMan.getGroupCalendar(bg);
+				SubscriptionContext subsContext = notificationManager.getSubscriptionContext(calRenderWrapper);
+				Publisher pub = nfm.getPublisher(subsContext);
+				if (pub != null) {
+					pub.setState(1); //int 0 is OK -> all other is not OK
+				}
 			}
 		}
 		//the course calendar
@@ -444,7 +449,7 @@ public class CourseFactory extends BasicManager {
 	 */
 	public static OLATResourceable copyCourse(OLATResourceable sourceRes, OLATResource targetRes) {
 		PersistingCourseImpl sourceCourse = (PersistingCourseImpl)loadCourse(sourceRes);
-		PersistingCourseImpl targetCourse = new PersistingCourseImpl(targetRes.getResourceableId());
+		PersistingCourseImpl targetCourse = new PersistingCourseImpl(targetRes);
 		File fTargetCourseBasePath = targetCourse.getCourseBaseContainer().getBasefile();
 		
 		//close connection before file copy
@@ -533,9 +538,9 @@ public class CourseFactory extends BasicManager {
 	 * @param zipFile
 	 * @return New Course.
 	 */
-	public static ICourse importCourseFromZip(OLATResourceable ores, File zipFile) {
+	public static ICourse importCourseFromZip(OLATResource ores, File zipFile) {
 		// Generate course with filesystem
-		PersistingCourseImpl newCourse = new PersistingCourseImpl(ores.getResourceableId());
+		PersistingCourseImpl newCourse = new PersistingCourseImpl(ores);
 		CourseConfigManagerImpl.getInstance().deleteConfigOf(newCourse);
 		
 		// Unzip course strucure in new course
@@ -736,7 +741,7 @@ public class CourseFactory extends BasicManager {
 			};
 		}, course.getResourceableId(), exportDirectory.getPath(), null, null, aLogV, uLogV, sLogV, charset, null, null);
 
-		PersistingCourseGroupManager.getInstance(course).archiveCourseGroups(exportDirectory);
+		course.getCourseEnvironment().getCourseGroupManager().archiveCourseGroups(exportDirectory);
 		
 		CoreSpringFactory.getImpl(ChatLogHelper.class).archive(course, exportDirectory);
 		
diff --git a/src/main/java/org/olat/course/PersistingCourseImpl.java b/src/main/java/org/olat/course/PersistingCourseImpl.java
index 2fd73da5d253447519644804fb799d53acf38a61..6b6c0b09239a2ad0cc41c8d39cb2deb8f18a6252 100644
--- a/src/main/java/org/olat/course/PersistingCourseImpl.java
+++ b/src/main/java/org/olat/course/PersistingCourseImpl.java
@@ -56,7 +56,6 @@ import org.olat.course.config.CourseConfig;
 import org.olat.course.config.CourseConfigManager;
 import org.olat.course.config.CourseConfigManagerImpl;
 import org.olat.course.export.CourseEnvironmentMapper;
-import org.olat.course.groupsandrights.PersistingCourseGroupManager;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.CourseNode.Processing;
 import org.olat.course.run.environment.CourseEnvironment;
@@ -123,14 +122,14 @@ public class PersistingCourseImpl implements ICourse, OLATResourceable, Serializ
 	 * not already exist. Editor and run structures are not yet set. Use load() to
 	 * initialize the editor and run structure from persisted XML structure.
 	 * 
-	 * @param resourceableId
+	 * @param resource The OLAT resource
 	 */
-	PersistingCourseImpl(Long resourceableId) {
-		this.resourceableId = resourceableId;
+	PersistingCourseImpl(OLATResource resource) {
+		this.resourceableId = resource.getResourceableId();
 		// prepare filesystem and set course base path and course folder paths
 		prepareFilesystem();
 		courseConfig = CourseConfigManagerImpl.getInstance().loadConfigFor(this); // load or init defaults
-		courseEnvironment = new CourseEnvironmentImpl(this);
+		courseEnvironment = new CourseEnvironmentImpl(this, resource);
 	}
 	
 	PersistingCourseImpl(RepositoryEntry courseEntry) {
@@ -293,12 +292,13 @@ public class PersistingCourseImpl implements ICourse, OLATResourceable, Serializ
 		FileUtils.copyFileToDir(new File(fCourseBase, CourseConfigManager.COURSECONFIG_XML), exportDirectory, "course export courseconfig");
 		
 		//export business groups
-		CourseEnvironmentMapper envMapper = PersistingCourseGroupManager.getInstance(this).getBusinessGroupEnvironment();
+		CourseEnvironmentMapper envMapper = getCourseEnvironment().getCourseGroupManager().getBusinessGroupEnvironment();
 		if(backwardsCompatible) {
 			//prevents duplicate names
 			envMapper.avoidDuplicateNames();
 		}
-		PersistingCourseGroupManager.getInstance(this).exportCourseBusinessGroups(fExportedDataDir, envMapper, runtimeDatas, backwardsCompatible);
+	
+		getCourseEnvironment().getCourseGroupManager().exportCourseBusinessGroups(fExportedDataDir, envMapper, runtimeDatas, backwardsCompatible);
 		if(backwardsCompatible) {
 			XStream xstream = CourseXStreamAliases.getReadCourseXStream();
 
diff --git a/src/main/java/org/olat/course/certificate/restapi/CertificationWebService.java b/src/main/java/org/olat/course/certificate/restapi/CertificationWebService.java
index e81ee18d64bad92c3395868be68398d26ab6c5b2..1d4e9b313ffb0611c147150d249be6fabf7d85bc 100644
--- a/src/main/java/org/olat/course/certificate/restapi/CertificationWebService.java
+++ b/src/main/java/org/olat/course/certificate/restapi/CertificationWebService.java
@@ -142,6 +142,9 @@ public class CertificationWebService {
 		}
 
 		VFSLeaf certificateFile = certificatesManager.getCertificateLeaf(certificate);
+		if(certificateFile == null || !certificateFile.exists()) {
+			return Response.serverError().status(Response.Status.NOT_FOUND).build();
+		}
 		return Response.ok(certificateFile.getInputStream()).build();
 	}
 	
diff --git a/src/main/java/org/olat/course/condition/NoOpCourseEnvironment.java b/src/main/java/org/olat/course/condition/NoOpCourseEnvironment.java
index 9e4ce4f31b63a1df11a54167b018732eb777b94d..0a75e272f70f1700b15004d64bc919b3a0bc2e42 100644
--- a/src/main/java/org/olat/course/condition/NoOpCourseEnvironment.java
+++ b/src/main/java/org/olat/course/condition/NoOpCourseEnvironment.java
@@ -51,13 +51,6 @@ public class NoOpCourseEnvironment implements CourseEnvironment {
 	// nothig special to do
 	}
 
-	/**
-	 * @see org.olat.course.run.environment.CourseEnvironment#isNoOpMode()
-	 */
-	public boolean isNoOpMode() {
-		return true;
-	}
-
 	/**
 	 * @see org.olat.course.run.environment.CourseEnvironment#getCurrentTimeMillis()
 	 *      This is not implemented in NoOpCourseEnvironment
diff --git a/src/main/java/org/olat/course/groupsandrights/CourseGroupManager.java b/src/main/java/org/olat/course/groupsandrights/CourseGroupManager.java
index 64f35d62cdafac83b9d02a7fd7234cf1277fa902..af5590bd3f645c6ae3beb062d6d92b41a5774b7c 100644
--- a/src/main/java/org/olat/course/groupsandrights/CourseGroupManager.java
+++ b/src/main/java/org/olat/course/groupsandrights/CourseGroupManager.java
@@ -208,6 +208,8 @@ public interface CourseGroupManager {
 	 */
 	public void exportCourseBusinessGroups(File fExportDirectory, CourseEnvironmentMapper env,
 			boolean runtimeDatas, boolean backwardsCompatible);
+	
+	public CourseEnvironmentMapper getBusinessGroupEnvironment();
 
 	/**
 	 * Import course internal groups fa previous export.
@@ -215,6 +217,8 @@ public interface CourseGroupManager {
 	 * @param fImportDirectory
 	 */
 	public CourseEnvironmentMapper importCourseBusinessGroups(File fImportDirectory);
+	
+	public void archiveCourseGroups(File exportDirectory);
 
 	/**
 	 * List with identities being coaches in learning groups of this course. If
@@ -226,8 +230,7 @@ public interface CourseGroupManager {
 	public List<Identity> getCoachesFromBusinessGroups();
 	
 	public List<Identity> getCoachesFromBusinessGroups(List<Long> groupKeys);
-	
-	//fxdiff VCRP-1,2: access control of resources
+
 	public List<Identity> getCoaches();
 
 	/**
@@ -252,9 +255,6 @@ public interface CourseGroupManager {
 	
 	public List<Identity> getParticipantsFromBusinessGroups(List<Long> groupKeys);
 	
-	
-	
-	//fxdiff VCRP-1,2: access control of resources
 	public List<Identity> getParticipants();
 
 	/**
@@ -273,4 +273,5 @@ public interface CourseGroupManager {
 	 * @return A list of all waiting-list groups where this identity is in
 	 */
 	public List<BusinessGroup> getWaitingListGroups(Identity identity);
+
 }
diff --git a/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java b/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java
index 97e4e5523786c533287cfda6df340390f5e4dc95..c568f181b047e753ce0fd47851723c2feaf1d7a4 100644
--- a/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java
+++ b/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java
@@ -125,7 +125,7 @@ public class PersistingCourseGroupManager extends BasicManager implements Course
 	 * @param course The current course
 	 * @return A course group manager that uses persisted data
 	 */
-	public static PersistingCourseGroupManager getInstance(OLATResourceable course) {
+	public static PersistingCourseGroupManager getInstance2(OLATResourceable course) {
 		return new PersistingCourseGroupManager(course);
 	}
 
@@ -387,7 +387,8 @@ public class PersistingCourseGroupManager extends BasicManager implements Course
 	@Override
 	public CourseEnvironmentMapper importCourseBusinessGroups(File fImportDirectory) {
 		CourseEnvironmentMapper envMapper = new CourseEnvironmentMapper();
-		RepositoryEntry courseRe = RepositoryManager.getInstance().lookupRepositoryEntry(getCourseResource(), true);
+		OLATResource resource = getCourseResource();
+		RepositoryEntry courseRe = RepositoryManager.getInstance().lookupRepositoryEntry(resource, true);
 		File fGroupXML1 = new File(fImportDirectory, LEARNINGGROUPEXPORT_XML);
 		if(fGroupXML1.exists()) {
 			BusinessGroupEnvironment env = businessGroupService.importGroups(courseRe, fGroupXML1);
diff --git a/src/main/java/org/olat/course/nodes/portfolio/_content/assessment_infos.html b/src/main/java/org/olat/course/nodes/portfolio/_content/assessment_infos.html
index b91f12596226dbc429881624785c6e0ac1a68908..6b4323a562f09a9abbf320e12c483b0214073818 100644
--- a/src/main/java/org/olat/course/nodes/portfolio/_content/assessment_infos.html
+++ b/src/main/java/org/olat/course/nodes/portfolio/_content/assessment_infos.html
@@ -1,78 +1,73 @@
-<div class="o_course_run_scoreinfo">
-	#if ($hasScoreField)
-		<h4>$r.translate("score.title")</h4>
-		<table>
-			<tbody>
-				<tr>
-					<td>
-						$r.translate("score.min"):
-					</td>
-					<td>
-						$scoreMin
-					</td>
-				</tr>
-				<tr>
-					<td>
-						$r.translate("score.max"): 
-					</td>
-					<td>
-						$scoreMax
-					</td>
-				</tr>
-				<tr>
-					<td>			
-						$r.translate("score.yourscore"): 
-					</td>
-					<td>
-						#if($score)		
-							$score
-						#else
-							<div class="o_course_run_scoreinfo_noinfo">$r.translate("score.noscore")</div>
-						#end
-					</td>
-				</tr>
-			</tbody>
-		</table>
-	#end
-	
-	#if ($hasPassedField)
-		<h4>$r.translate("passed.title")</h4>
-		<table>
-			<tbody>	
-			#if ($passedCutValue)
-				<tr>
-					<td>
-						$r.translate("passed.cut"):
-					</td>
-					<td>
-						$passedCutValue
-					</td>
-				</tr>
+#if ($hasScoreField || $hasPassedField)
+
+<div class="panel panel-default o_personal">
+  	<div class="panel-heading">
+ 			<h4 class="panel-title">$r.translate("score.title")</h4>
+ 		</div>
+	<table class="table">
+	<tbody>
+		#if ($hasScoreField)
+		<tr class="o_score_config_min">
+			<th>$r.translate("score.min")</th>
+			<td>$scoreMin</td>
+		</tr>
+		<tr class="o_score_config_max">
+			<th>$r.translate("score.max")</th>
+			<td>$scoreMax</td>
+		</tr>
+		<tr class="o_score">
+			<th>$r.translate("score.yourscore")</th>
+			<td>
+			#if($score)		
+				$score
+			#else
+				<div class="o_noinfo">$r.translate("score.noscore")</div>
+			#end				
+			</td> 
+		</tr>
+		#end 
+		
+		#if ($hasPassedField)
+		#if ($passedCutValue)
+		<tr class="o_cutval">
+			<th>$r.translate("passed.cut")</th>
+			<td>$passedCutValue</td>
+		</tr>
+		#end
+		<tr class="o_state #if ($hasPassedValue && $passed) o_passed #elseif($hasPassedValue && !$passed) o_failed #else o_unknown #end">
+			<th>$r.translate("passed.yourpassed")</th>
+			<td>
+			#if($hasPassedValue && $passed)	
+				<i class="o_icon o_icon_passed"></i> $r.translate("map.passed")
+			#elseif($hasPassedValue && !$passed)		
+				<i class="o_icon o_icon_failed"></i> $r.translate("map.not.passed")
+			#else
+				<div class="o_noinfo">$r.translate("map.not.rated.yet")</div>
 			#end
-				<tr>
-					<td>			
-						$r.translate("passed.yourpassed"):
-					</td>
-					<td>
-						#if($hasPassedValue && $passed == true)		
-							<span class="o_state o_passed">$r.translate("map.passed")</span>
-						#elseif($hasPassedValue && $passed == false)		
-							<span class="o_state o_failed"><i class="o_icon o_icon_failed"> </i> $r.translate("map.not.passed")</span>
-						#else
-							<div class="o_course_run_scoreinfo_noinfo">$r.translate("map.not.rated.yet")</div>
-						#end
-					</td>
-				</tr>
-			</tbody>
-		</table>
-	#end
-	
-	#if ($hasCommentField)
-		<h4>$r.translate("map.comment")</h4>
-		#if ($comment)
-			$comment
-		#else
-			<div class="o_course_run_scoreinfo_noinfo">$r.translate("comment.nocomment")</div>
+			</td>
+		</tr>
 		#end
-	#end
-</div>
\ No newline at end of file
+	</tbody>
+	</table>
+</div>
+#end
+	
+#if ($comment && !$comment.isEmpty())
+<div class="panel panel-default o_comment">
+  	<div class="panel-heading" data-toggle="collapse" data-target="#collapseComment">
+  		<h4 class="panel-title">
+  			<i id="collapseCommentToggler" class="o_icon o_icon-fw o_icon_close_togglebox"> </i> $r.translate("map.comment")</h4>
+  	</div>
+	<div id="collapseComment" class="panel-collapse collapse in"><div class="panel-body">$comment</div></div>
+</div>
+<script type="text/javascript">
+	/* <![CDATA[ */
+		jQuery('#collapseComment').on('hide.bs.collapse', function () {
+				jQuery('#collapseCommentToggler').removeClass('o_icon_close_togglebox').addClass('o_icon_open_togglebox');
+		})
+		jQuery('#collapseComment').on('show.bs.collapse', function () {
+				jQuery('#collapseCommentToggler').removeClass('o_icon_open_togglebox').addClass('o_icon_close_togglebox');
+		})
+	/* ]]> */
+</script>
+#end
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/portfolio/_content/run.html b/src/main/java/org/olat/course/nodes/portfolio/_content/run.html
index a955095c37075c178fe3524cd4e0f99983632281..8d4386aad30b4b393e9475244394cc3b202b2eca 100644
--- a/src/main/java/org/olat/course/nodes/portfolio/_content/run.html
+++ b/src/main/java/org/olat/course/nodes/portfolio/_content/run.html
@@ -1,2 +1,2 @@
-$r.render("infos")
-$r.render("assessmentInfos")
\ No newline at end of file
+$r.render("assessmentInfos")
+$r.render("infos")
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java b/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java
index 80538d7fb13288419867f306d2bf7a4822a289fb..d0710faafc39a6405ac29de56a5e352ab1700aca 100644
--- a/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java
+++ b/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java
@@ -53,7 +53,6 @@ import org.olat.group.BusinessGroupService;
 import org.olat.group.ui.edit.BusinessGroupModifiedEvent;
 import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
-import org.olat.repository.RepositoryManager;
 import org.olat.resource.OLATResource;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -71,8 +70,6 @@ public class ProjectGroupManagerImpl extends BasicManager implements ProjectGrou
 	@Autowired
 	private BaseSecurity securityManager;
 	@Autowired
-	private RepositoryManager repositoryManager;
-	@Autowired
 	private ProjectBrokerManager projectBrokerManager;
 	@Autowired
 	private BusinessGroupService businessGroupService;
@@ -114,7 +111,7 @@ public class ProjectGroupManagerImpl extends BasicManager implements ProjectGrou
 			}
 		} else {
 			logDebug("No group for project-broker exist => create a new one");
-			RepositoryEntry re = repositoryManager.lookupRepositoryEntry(cpm.getCourseResource(), false);
+			RepositoryEntry re = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
 			accountManagerGroup = businessGroupService.createBusinessGroup(identity, groupName, groupDescription, -1, -1, false, false, re);
 			int i = 2;
 			while (accountManagerGroup == null) {
@@ -188,9 +185,9 @@ public class ProjectGroupManagerImpl extends BasicManager implements ProjectGrou
 	////////////////////////////
 	// PROJECT GROUP MANAGEMENT
 	////////////////////////////
+	@Override
 	public BusinessGroup createProjectGroupFor(Long projectBrokerId, Identity identity, String groupName, String groupDescription, Long courseId) {
 		CourseGroupManager cgm = CourseFactory.loadCourse(courseId).getCourseEnvironment().getCourseGroupManager();
-		OLATResource resource = cgm.getCourseResource();
 		RepositoryEntry re = cgm.getCourseEntry();
 
 		logDebug("createProjectGroupFor groupName=" + groupName);
@@ -206,7 +203,8 @@ public class ProjectGroupManagerImpl extends BasicManager implements ProjectGrou
 		logDebug("Created a new projectGroup=" + projectGroup);
 		return projectGroup;
 	}
-	
+
+	@Override
 	public void deleteProjectGroupFor(Project project) {
 		BusinessGroupService bgs = businessGroupService;
 		bgs.deleteBusinessGroup(project.getProjectGroup());
diff --git a/src/main/java/org/olat/course/properties/CoursePropertyManager.java b/src/main/java/org/olat/course/properties/CoursePropertyManager.java
index c2ac060d12e76c2a926a7a3bc6d13eac2ca37cea..611a280a0857c7d56bb0f6192642cc8b92ea3128 100644
--- a/src/main/java/org/olat/course/properties/CoursePropertyManager.java
+++ b/src/main/java/org/olat/course/properties/CoursePropertyManager.java
@@ -33,7 +33,6 @@ import org.olat.course.nodes.CourseNode;
 import org.olat.group.BusinessGroup;
 import org.olat.ims.qti.export.helper.IdentityAnonymizerCallback;
 import org.olat.properties.Property;
-import org.olat.resource.OLATResource;
 
 /**
  * Initial Date:  08.02.2005
@@ -41,8 +40,6 @@ import org.olat.resource.OLATResource;
  * @author Mike Stock
  */
 public interface CoursePropertyManager extends IdentityAnonymizerCallback {
-
-	public OLATResource getCourseResource();
 	
 	/**
 	 * Create a course node property in ram
diff --git a/src/main/java/org/olat/course/properties/PersistingCoursePropertyManager.java b/src/main/java/org/olat/course/properties/PersistingCoursePropertyManager.java
index 08f9f11930e54f18b26b38eac23e1d766010d14d..50b028eca896a4c58258698467e6423d8b609c33 100644
--- a/src/main/java/org/olat/course/properties/PersistingCoursePropertyManager.java
+++ b/src/main/java/org/olat/course/properties/PersistingCoursePropertyManager.java
@@ -42,8 +42,6 @@ import org.olat.group.BusinessGroup;
 import org.olat.modules.assessment.manager.AssessmentEntryDAO;
 import org.olat.properties.NarrowedPropertyManager;
 import org.olat.properties.Property;
-import org.olat.resource.OLATResource;
-import org.olat.resource.OLATResourceManager;
 
 /**
  * Initial Date: May 5, 2004
@@ -79,10 +77,6 @@ public class PersistingCoursePropertyManager implements CoursePropertyManager {
 	public static PersistingCoursePropertyManager getInstance(OLATResourceable course) {
 		return new PersistingCoursePropertyManager(course);
 	}
-	
-	public OLATResource getCourseResource() {
-		return OLATResourceManager.getInstance().findResourceable(ores);
-	}
 
 	/**
 	 * @see org.olat.course.properties.CoursePropertyManager#createCourseNodePropertyInstance(org.olat.course.nodes.CourseNode,
diff --git a/src/main/java/org/olat/course/run/environment/CourseEnvironment.java b/src/main/java/org/olat/course/run/environment/CourseEnvironment.java
index c591e97ab37f3ce0d914f20e6f50ac4e4a8479d7..7763083ba82ab3b3a8568ca5063638fe5b6ad90d 100644
--- a/src/main/java/org/olat/course/run/environment/CourseEnvironment.java
+++ b/src/main/java/org/olat/course/run/environment/CourseEnvironment.java
@@ -50,14 +50,6 @@ public interface CourseEnvironment {
 	 * @return The current time in millis
 	 */
 	public long getCurrentTimeMillis();
-	
-	/**
-	 * if true then all ConditionInterpreter functions should return true/1 immediately without e.g. accessing the database. 
-	 * We use this as validating of the syntax before saving it, so that there are only grammatically correct
-	 * expressions which are saved and therefore are evaluated in the run mode later.
-	 * @return true if no op mode
-	 */
-	public boolean isNoOpMode();
 
 	/**
 	 * Get the course group management environment
diff --git a/src/main/java/org/olat/course/run/environment/CourseEnvironmentImpl.java b/src/main/java/org/olat/course/run/environment/CourseEnvironmentImpl.java
index 97649704ecbc71f464bf0895bb0c9e67b938494b..22004f11f31da49e23803f0325101d331ee54bf2 100644
--- a/src/main/java/org/olat/course/run/environment/CourseEnvironmentImpl.java
+++ b/src/main/java/org/olat/course/run/environment/CourseEnvironmentImpl.java
@@ -40,6 +40,7 @@ import org.olat.course.groupsandrights.PersistingCourseGroupManager;
 import org.olat.course.properties.CoursePropertyManager;
 import org.olat.course.properties.PersistingCoursePropertyManager;
 import org.olat.repository.RepositoryEntry;
+import org.olat.resource.OLATResource;
 
 /**
  * Initial Date: 09.03.2004
@@ -58,11 +59,12 @@ public class CourseEnvironmentImpl implements CourseEnvironment {
 	 * Constructor for the course environment
 	 * 
 	 * @param course The course
+	 * @param resource The OLAT resource
 	 */
-	public CourseEnvironmentImpl(PersistingCourseImpl course) {
+	public CourseEnvironmentImpl(PersistingCourseImpl course, OLATResource resource) {
 		this.course = course;
 		this.propertyManager = PersistingCoursePropertyManager.getInstance(course);
-		this.cgm = PersistingCourseGroupManager.getInstance(course);
+		this.cgm = PersistingCourseGroupManager.getInstance(resource);
 	}
 	
 	public CourseEnvironmentImpl(PersistingCourseImpl course, RepositoryEntry courseEntry) {
@@ -82,13 +84,6 @@ public class CourseEnvironmentImpl implements CourseEnvironment {
 		return System.currentTimeMillis();
 	}
 
-	/**
-	 * @see org.olat.course.run.environment.CourseEnvironment#isNoOpMode()
-	 */
-	public boolean isNoOpMode() {
-		return false;
-	}
-
 	/**
 	 * @see org.olat.course.run.environment.CourseEnvironment#getCourseGroupManager()
 	 */
diff --git a/src/main/java/org/olat/course/run/preview/PreviewCourseEnvironment.java b/src/main/java/org/olat/course/run/preview/PreviewCourseEnvironment.java
index 50e0f4b35c4aa0737469b329e41e9170b0208188..516e22edabe70d636e97d39d7e65f4b4ac2467e2 100644
--- a/src/main/java/org/olat/course/run/preview/PreviewCourseEnvironment.java
+++ b/src/main/java/org/olat/course/run/preview/PreviewCourseEnvironment.java
@@ -79,13 +79,6 @@ final class PreviewCourseEnvironment implements CourseEnvironment {
 		return simulatedDateTime;
 	}
 
-	/**
-	 * @see org.olat.course.run.environment.CourseEnvironment#isNoOpMode()
-	 */
-	public boolean isNoOpMode() {
-		return false;
-	}
-
 	/**
 	 * @see org.olat.course.run.environment.CourseEnvironment#getCourseGroupManager()
 	 */
diff --git a/src/main/java/org/olat/course/run/preview/PreviewCourseGroupManager.java b/src/main/java/org/olat/course/run/preview/PreviewCourseGroupManager.java
index 36313080a36043de41eeb37e94f5302fa577c8f9..69b0806b006d92c8e5829cfc8d7be7d9f70de357 100644
--- a/src/main/java/org/olat/course/run/preview/PreviewCourseGroupManager.java
+++ b/src/main/java/org/olat/course/run/preview/PreviewCourseGroupManager.java
@@ -285,7 +285,6 @@ final class PreviewCourseGroupManager extends BasicManager implements CourseGrou
 		throw new AssertException("unsupported");
 	}
 	
-	//fxdiff VCRP-1,2: access control of resources
 	@Override
 	public List<Identity> getCoaches() {
 		throw new AssertException("unsupported");
@@ -296,6 +295,11 @@ final class PreviewCourseGroupManager extends BasicManager implements CourseGrou
 		throw new AssertException("unsupported");
 	}
 
+	@Override
+	public CourseEnvironmentMapper getBusinessGroupEnvironment() {
+		throw new AssertException("unsupported");
+	}
+
 	@Override
 	public void exportCourseBusinessGroups(File fExportDirectory, CourseEnvironmentMapper env,
 			boolean runtimeDatas, boolean backwardsCompatible) {
@@ -307,6 +311,11 @@ final class PreviewCourseGroupManager extends BasicManager implements CourseGrou
 		throw new AssertException("unsupported");
 	}
 
+	@Override
+	public void archiveCourseGroups(File exportDirectory) {
+		//
+	}
+
 	@Override
 	public List<BusinessGroup> getWaitingListGroups(Identity identity) {
 		throw new AssertException("unsupported");
diff --git a/src/main/java/org/olat/course/run/preview/PreviewCoursePropertyManager.java b/src/main/java/org/olat/course/run/preview/PreviewCoursePropertyManager.java
index 2454bc3fd260bf4edf5a81f44efa0c6db9ecce7a..bba1a0b620292d7cd246a162715d33d2b8ad8dbf 100644
--- a/src/main/java/org/olat/course/run/preview/PreviewCoursePropertyManager.java
+++ b/src/main/java/org/olat/course/run/preview/PreviewCoursePropertyManager.java
@@ -40,7 +40,6 @@ import org.olat.course.properties.CoursePropertyManager;
 import org.olat.group.BusinessGroup;
 import org.olat.properties.Property;
 import org.olat.properties.PropertyManager;
-import org.olat.resource.OLATResource;
 
 /**
  * Initial Date:  08.02.2005
@@ -61,11 +60,6 @@ final class PreviewCoursePropertyManager extends BasicManager implements CourseP
 		//
 	}
 
-	@Override
-	public OLATResource getCourseResource() {
-		return null;
-	}
-
 	/**
 	 * @see org.olat.course.properties.CoursePropertyManager#createCourseNodePropertyInstance(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, org.olat.group.BusinessGroup, java.lang.String, java.lang.Float, java.lang.Long, java.lang.String, java.lang.String)
 	 */
diff --git a/src/main/java/org/olat/repository/handlers/CourseHandler.java b/src/main/java/org/olat/repository/handlers/CourseHandler.java
index 40acd4e26474fb8bf02b96c3807fd5f582af210c..c99f5e4c87c0ff6bab8087f6383e75091a264f0d 100644
--- a/src/main/java/org/olat/repository/handlers/CourseHandler.java
+++ b/src/main/java/org/olat/repository/handlers/CourseHandler.java
@@ -221,15 +221,11 @@ public class CourseHandler implements RepositoryHandler {
 		if (course == null) {
 			return null;
 		}
-		
-		CourseGroupManager cgm = course.getCourseEnvironment().getCourseGroupManager();
-		OLATResource courseResource = cgm.getCourseResource();
-		
+
 		RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class);
 		RepositoryEntry re = repositoryService
-				.create(initialAuthor, null, "", displayname, description, courseResource, RepositoryEntry.ACC_OWNERS);
+				.create(initialAuthor, null, "", displayname, description, newCourseResource, RepositoryEntry.ACC_OWNERS);
 		DBFactory.getInstance().commit();
-		
 
 		// create empty run structure
 		course = CourseFactory.openCourseEditSession(course.getResourceableId());
@@ -248,7 +244,7 @@ public class CourseHandler implements RepositoryHandler {
 		}
 
 		// create group management / import groups
-		cgm = course.getCourseEnvironment().getCourseGroupManager();
+		CourseGroupManager cgm = course.getCourseEnvironment().getCourseGroupManager();
 		File fImportBaseDirectory = course.getCourseExportDataDir().getBasefile();
 		CourseEnvironmentMapper envMapper = cgm.importCourseBusinessGroups(fImportBaseDirectory);
 		envMapper.setAuthor(initialAuthor);
@@ -414,7 +410,7 @@ public class CourseHandler implements RepositoryHandler {
 		//transaction copied
 		ICourse sourceCourse = CourseFactory.loadCourse(source);
 		CourseGroupManager sourceCgm = sourceCourse.getCourseEnvironment().getCourseGroupManager();
-		CourseEnvironmentMapper env = PersistingCourseGroupManager.getInstance(sourceCourse).getBusinessGroupEnvironment();
+		CourseEnvironmentMapper env = PersistingCourseGroupManager.getInstance(sourceResource).getBusinessGroupEnvironment();
 			
 		File fExportDir = new File(WebappHelper.getTmpDir(), UUID.randomUUID().toString());
 		fExportDir.mkdirs();
diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
index bbbf8b756a4777668446309a4c705fa2b92adb37..8b1a357b4313971fe0b7b8e8f78f37f06ee63b37 100644
--- a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
+++ b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java
@@ -556,6 +556,9 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController
 		} else if(detailsCtrl == source) {
 			if(event instanceof LeavingEvent) {
 				doClose(ureq);
+			} else if(event == Event.DONE_EVENT) {
+				popToRoot(ureq);
+				cleanUp();
 			}
 		} else if(closeCtrl == source) {
 			if(event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
@@ -670,7 +673,7 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController
 	
 	protected void doDetails(UserRequest ureq) {
 		WindowControl bwControl = getSubWindowControl("Infos");
-		RepositoryEntryDetailsController ctrl = new RepositoryEntryDetailsController(ureq, addToHistory(ureq, bwControl), re);
+		RepositoryEntryDetailsController ctrl = new RepositoryEntryDetailsController(ureq, addToHistory(ureq, bwControl), re, true);
 		listenTo(ctrl);
 		detailsCtrl = pushController(ureq, translate("details.header"), ctrl);
 		currentToolCtr = detailsCtrl;
diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
index 4192c408bbb6c95edae7ea31c91df341ddba9932..4a194751f4597bdc0a5169eae4b1c50d740538a5 100644
--- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
+++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDetailsController.java
@@ -79,7 +79,6 @@ import org.olat.login.LoginModule;
 import org.olat.repository.CatalogEntry;
 import org.olat.repository.LeavingStatusList;
 import org.olat.repository.RepositoryEntry;
-import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryModule;
 import org.olat.repository.RepositoryService;
@@ -120,6 +119,7 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 	protected RepositoryEntry entry;
 	protected RepositoryEntryRow row;
 	private Integer index;
+	private final boolean inRuntime;
 
 	@Autowired
 	private LoginModule loginModule;
@@ -155,30 +155,25 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 	private String baseUrl;
 	private final boolean guestOnly;
 	
-	public RepositoryEntryDetailsController(UserRequest ureq, WindowControl wControl, RepositoryEntryRow row) {
-		this(ureq, wControl);
+	public RepositoryEntryDetailsController(UserRequest ureq, WindowControl wControl, RepositoryEntryRow row, boolean inRuntime) {
+		this(ureq, wControl, inRuntime);
 		this.row = row;
 		entry = repositoryService.loadByKey(row.getKey());
 		initForm(ureq);
 	}
 	
-	public RepositoryEntryDetailsController(UserRequest ureq, WindowControl wControl, RepositoryEntryRef ref) {
-		this(ureq, wControl);
-		entry = repositoryService.loadByKey(ref.getKey());
-		initForm(ureq);
-	}
-	
-	public RepositoryEntryDetailsController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) {
-		this(ureq, wControl);
+	public RepositoryEntryDetailsController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry, boolean inRuntime) {
+		this(ureq, wControl, inRuntime);
 		this.entry = entry;
 		initForm(ureq);
 	}
 	
-	private RepositoryEntryDetailsController(UserRequest ureq, WindowControl wControl) {
+	private RepositoryEntryDetailsController(UserRequest ureq, WindowControl wControl, boolean inRuntime) {
 		super(ureq, wControl, Util.getPackageVelocityRoot(RepositoryEntryDetailsController.class) + "/details.html");
 		setTranslator(Util.createPackageTranslator(RepositoryService.class, getLocale(), getTranslator()));
 		setTranslator(Util.createPackageTranslator(RestapiAdminController.class, getLocale(), getTranslator()));
 		guestOnly = ureq.getUserSession().getRoles().isGuestOnly();
+		this.inRuntime = inRuntime;
 
 		OLATResourceable ores = OresHelper.createOLATResourceableType("MyCoursesSite");
 		ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
@@ -598,12 +593,16 @@ public class RepositoryEntryDetailsController extends FormBasicController {
 	}
 	
 	protected void doStart(UserRequest ureq) {
-		try {
-			String businessPath = "[RepositoryEntry:" + entry.getKey() + "]";
-			NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
-		} catch (CorruptedCourseException e) {
-			logError("Course corrupted: " + entry.getKey() + " (" + entry.getOlatResource().getResourceableId() + ")", e);
-			showError("cif.error.corrupted");
+		if(inRuntime) {
+			fireEvent(ureq, Event.DONE_EVENT);
+		} else {
+			try {
+				String businessPath = "[RepositoryEntry:" + entry.getKey() + "]";
+				NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
+			} catch (CorruptedCourseException e) {
+				logError("Course corrupted: " + entry.getKey() + " (" + entry.getOlatResource().getResourceableId() + ")", e);
+				showError("cif.error.corrupted");
+			}
 		}
 	}
 	
diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
index a0c505675ec7b1d1f4f334b784a0ccf627c16226..f96b33cad974e22452b7d08358290a8e8b3a4d18 100644
--- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
+++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java
@@ -502,7 +502,7 @@ public class RepositoryEntryListController extends FormBasicController
 			
 			OLATResourceable ores = OresHelper.createOLATResourceableInstance("Infos", 0l);
 			WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
-			detailsCtrl = new RepositoryEntryDetailsController(ureq, bwControl, row);
+			detailsCtrl = new RepositoryEntryDetailsController(ureq, bwControl, row, false);
 			listenTo(detailsCtrl);
 			addToHistory(ureq, detailsCtrl);
 			
diff --git a/src/test/java/org/olat/course/editor/PublishProcessTest.java b/src/test/java/org/olat/course/editor/PublishProcessTest.java
index 97c8f86c7e0201dc31b8bb9d5d300eeffaf6de30..e301ff32fbc4b1a0fce07e3e671efd8795866dcd 100644
--- a/src/test/java/org/olat/course/editor/PublishProcessTest.java
+++ b/src/test/java/org/olat/course/editor/PublishProcessTest.java
@@ -327,17 +327,14 @@ public class PublishProcessTest extends OlatTestCase {
 			softKey = importExport.getSoftkey();
 		}
 		
-		newCourseResource = olatResourceManager.findOrPersistResourceable(newCourseResource);
 		RepositoryEntry re = repositoryService.create(importExport.getInitialAuthor(), importExport.getResourceName(),
 				importExport.getDisplayName(), importExport.getDescription(), newCourseResource);
 		// ok, continue import
-		re.setOlatResource(newCourseResource);
 		re.setSoftkey(softKey);
 		// set access configuration
 		re.setAccess(access);
-
 		// save the repository entry
-		repositoryService.update(re);
+		re = repositoryService.update(re);
 
 		//import groups
 		course = CourseFactory.openCourseEditSession(course.getResourceableId());
diff --git a/src/test/java/org/olat/restapi/CertificationTest.java b/src/test/java/org/olat/restapi/CertificationTest.java
index fd629f65ac69b78447d478302655a8a5a5e1ec8b..37037b0d7b2cc60ccfa2b3934f777fd8cb7b9618 100644
--- a/src/test/java/org/olat/restapi/CertificationTest.java
+++ b/src/test/java/org/olat/restapi/CertificationTest.java
@@ -26,6 +26,7 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.concurrent.Callable;
 
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriBuilder;
@@ -45,6 +46,7 @@ import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.course.certificate.Certificate;
+import org.olat.course.certificate.CertificateStatus;
 import org.olat.course.certificate.CertificatesManager;
 import org.olat.course.certificate.model.CertificateInfos;
 import org.olat.repository.RepositoryEntry;
@@ -80,7 +82,18 @@ public class CertificationTest extends OlatJerseyTestCase {
 		Certificate certificate = certificatesManager.generateCertificate(certificateInfos, entry, null, false);
 		dbInstance.commitAndCloseSession();
 		Assert.assertNotNull(certificate);
-
+		
+		//wait until the certificate is created
+		waitForCondition(new Callable<Boolean>() {
+			@Override
+			public Boolean call() throws Exception {
+				Certificate reloadedCertificate = certificatesManager.getCertificateById(certificate.getKey());
+				return CertificateStatus.ok.equals(reloadedCertificate.getStatus());
+			}
+			
+			
+		}, 30000);
+		
 		URI uri = UriBuilder.fromUri(getContextURI()).path("repo").path("courses")
 				.path(entry.getOlatResource().getKey().toString())
 				.path("certificates").path(assessedIdentity.getKey().toString()).build();
diff --git a/src/test/java/org/olat/restapi/MyForumsTest.java b/src/test/java/org/olat/restapi/MyForumsTest.java
index dfe58e39ebfea4c91445c4649011da098b766b26..fcbc58a25e31385650a00c60f92280c5d9d76c21 100644
--- a/src/test/java/org/olat/restapi/MyForumsTest.java
+++ b/src/test/java/org/olat/restapi/MyForumsTest.java
@@ -43,7 +43,6 @@ import javax.ws.rs.core.UriBuilder;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.commons.services.notifications.NotificationsManager;
@@ -74,28 +73,10 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class MyForumsTest extends OlatJerseyTestCase {
 
-	private static boolean setup;
-	private static ICourse myCourse;
-	private static RepositoryEntry myCourseRe;
-	
+
 	@Autowired
 	private DB dbInstance;
-	
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		
-		if(setup) return;
-		
-		URL courseWithForumsUrl = MyForumsTest.class.getResource("myCourseWS.zip");
-		Assert.assertNotNull(courseWithForumsUrl);
-		File courseWithForums = new File(courseWithForumsUrl.toURI());
-		myCourseRe = CourseFactory.deployCourseFromZIP(courseWithForums, null, 4);	
-		Assert.assertNotNull(myCourseRe);
-		myCourse = CourseFactory.loadCourse(myCourseRe.getOlatResource().getResourceableId());
 
-		setup = true;
-	}
 	
 	/**
 	 * Test retrieve the forum which the user subscribe in a course.
@@ -104,6 +85,13 @@ public class MyForumsTest extends OlatJerseyTestCase {
 	 */
 	@Test
 	public void myForums() throws IOException, URISyntaxException {
+		URL courseWithForumsUrl = MyForumsTest.class.getResource("myCourseWS.zip");
+		Assert.assertNotNull(courseWithForumsUrl);
+		File courseWithForums = new File(courseWithForumsUrl.toURI());
+		RepositoryEntry myCourseRe = CourseFactory.deployCourseFromZIP(courseWithForums, null, 4);	
+		Assert.assertNotNull(myCourseRe);
+		ICourse myCourse = CourseFactory.loadCourse(myCourseRe.getOlatResource().getResourceableId());
+		
 		final Identity id = JunitTestHelper.createAndPersistIdentityAsUser("my-" + UUID.randomUUID().toString());
 		dbInstance.commitAndCloseSession();