diff --git a/src/main/java/org/olat/course/nodes/SurveyCourseNode.java b/src/main/java/org/olat/course/nodes/SurveyCourseNode.java
index 211d190917f88f9fa6b9d1fda871bfc8fd5fd68b..6e4fbbf0e173f6e1f5520dbc2ecf19aa2e13a815 100644
--- a/src/main/java/org/olat/course/nodes/SurveyCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/SurveyCourseNode.java
@@ -46,10 +46,10 @@ import org.olat.course.editor.CourseEditorEnv;
 import org.olat.course.editor.NodeEditController;
 import org.olat.course.editor.StatusDescription;
 import org.olat.course.export.CourseEnvironmentMapper;
-import org.olat.course.nodes.survey.SurveyEditController;
-import org.olat.course.nodes.survey.SurveyRunController;
 import org.olat.course.nodes.survey.SurveyRunSecurityCallback;
-import org.olat.course.nodes.survey.SurveyStatisticResourceResult;
+import org.olat.course.nodes.survey.ui.SurveyEditController;
+import org.olat.course.nodes.survey.ui.SurveyRunController;
+import org.olat.course.nodes.survey.ui.SurveyStatisticResourceResult;
 import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.userview.CourseNodeSecurityCallback;
 import org.olat.course.run.userview.UserCourseEnvironment;
@@ -142,7 +142,7 @@ public class SurveyCourseNode extends AbstractAccessableCourseNode {
 	public TabbableController createEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
 			ICourse course, UserCourseEnvironment euce) {
 		updateModuleConfigDefaults(false);
-		TabbableController childTabCntrllr	= new SurveyEditController(ureq, wControl, this, course);
+		TabbableController childTabCntrllr	= new SurveyEditController(ureq, wControl, this, euce);
 		CourseNode chosenNode = course.getEditorTreeModel().getCourseNode(euce.getCourseEditorEnv().getCurrentCourseNodeId());
 		return new NodeEditController(ureq, wControl, course, chosenNode, euce, childTabCntrllr);
 	}
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyLearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/survey/SurveyLearningPathNodeHandler.java
index 5763781bc83dfa712381ae674a1ea235847e57f9..fcf21f215e8c60a8bc5c435b594a89fd55b0a5dc 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyLearningPathNodeHandler.java
+++ b/src/main/java/org/olat/course/nodes/survey/SurveyLearningPathNodeHandler.java
@@ -31,6 +31,7 @@ import org.olat.course.learningpath.ui.LearningPathNodeConfigController;
 import org.olat.course.learningpath.ui.LearningPathNodeConfigController.LearningPathControllerConfig;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.SurveyCourseNode;
+import org.olat.course.nodes.survey.ui.SurveyRunController;
 import org.springframework.stereotype.Service;
 
 /**
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyManager.java b/src/main/java/org/olat/course/nodes/survey/SurveyManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b7971b137b1676776fee02292516d4056f2bc54
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/survey/SurveyManager.java
@@ -0,0 +1,76 @@
+/**
+ * <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.course.nodes.survey;
+
+import java.io.File;
+
+import org.olat.core.id.Identity;
+import org.olat.core.util.UserSession;
+import org.olat.course.nodes.SurveyCourseNode;
+import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.modules.ceditor.DataStorage;
+import org.olat.modules.forms.EvaluationFormParticipation;
+import org.olat.modules.forms.EvaluationFormSession;
+import org.olat.modules.forms.EvaluationFormSurvey;
+import org.olat.modules.forms.EvaluationFormSurveyIdentifier;
+import org.olat.modules.forms.model.xml.Form;
+import org.olat.repository.RepositoryEntry;
+
+/**
+ * 
+ * Initial date: 10 Sep 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public interface SurveyManager {
+
+	public EvaluationFormSurveyIdentifier getSurveyIdentifier(SurveyCourseNode surveyCourseNode,
+			UserCourseEnvironment userCourseEnv);
+
+	public EvaluationFormSurvey loadSurvey(EvaluationFormSurveyIdentifier surveyIdent);
+
+	public boolean isFormUpdateable(EvaluationFormSurvey survey);
+
+	public EvaluationFormSurvey updateSurveyForm(EvaluationFormSurvey survey, RepositoryEntry formEntry);
+
+	public EvaluationFormSurvey createSurvey(EvaluationFormSurveyIdentifier surveyIdent, RepositoryEntry formEntry);
+
+	public Form loadForm(EvaluationFormSurvey survey);
+
+	public File getFormFile(EvaluationFormSurvey survey);
+
+	public DataStorage loadStorage(EvaluationFormSurvey survey);
+
+	public EvaluationFormParticipation loadOrCreateParticipation(EvaluationFormSurvey survey, Identity identity);
+
+	public EvaluationFormParticipation loadOrCreateGuestParticipation(EvaluationFormSurvey survey,
+			UserSession userSession);
+
+	public EvaluationFormSession loadOrCreateSesssion(EvaluationFormParticipation participation);
+
+	public void onExecutionStarted(SurveyCourseNode courseNode, UserCourseEnvironment userCourseEnv);
+
+	public void onExecutionFinished(SurveyCourseNode courseNode, UserCourseEnvironment userCourseEnv);
+
+	public long getCountOfSessions(EvaluationFormSurvey survey);
+
+	public void deleteAllData(EvaluationFormSurvey survey);
+
+}
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyRunSecurityCallback.java b/src/main/java/org/olat/course/nodes/survey/SurveyRunSecurityCallback.java
index e14674d4fb7dd3e5f1f675e9c9c47821a5c6198a..15b5a64dac75c1ba6751db89d20c40f3b7ef7579 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyRunSecurityCallback.java
+++ b/src/main/java/org/olat/course/nodes/survey/SurveyRunSecurityCallback.java
@@ -47,15 +47,15 @@ public class SurveyRunSecurityCallback {
 		this.canRunCommands = userCourseEnv.isAdmin();
 	}
 
-	boolean isGuestOnly() {
+	public boolean isGuestOnly() {
 		return guestOnly;
 	}
 
-	boolean isExecutor() {
+	public boolean isExecutor() {
 		return executor;
 	}
 
-	boolean isReportViewer() {
+	public boolean isReportViewer() {
 		return reportViewer;
 	}
 
@@ -107,15 +107,15 @@ public class SurveyRunSecurityCallback {
 		return false;
 	}
 	
-	boolean canParticipate() {
+	public boolean canParticipate() {
 		return isExecutor() && !courseReadOnly;
 	}
 	
-	boolean hasParticipated(EvaluationFormParticipation participation) {
+	public boolean hasParticipated(EvaluationFormParticipation participation) {
 		return participation != null && EvaluationFormParticipationStatus.done.equals(participation.getStatus());
 	}
 
-	boolean canExecute(EvaluationFormParticipation participation) {
+	public boolean canExecute(EvaluationFormParticipation participation) {
 		return participation != null && isExecutor() && !hasParticipated(participation);
 	}
 	
@@ -134,7 +134,7 @@ public class SurveyRunSecurityCallback {
 		return false;
 	}
 
-	boolean isReadOnly() {
+	public boolean isReadOnly() {
 		return courseReadOnly && isExecutor();
 	}
 
@@ -142,6 +142,4 @@ public class SurveyRunSecurityCallback {
 		return canRunCommands;
 	}
 
-
-
 }
diff --git a/src/main/java/org/olat/course/nodes/survey/manager/SurveyManagerImpl.java b/src/main/java/org/olat/course/nodes/survey/manager/SurveyManagerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..64d643b739ea05c374538293bc43b6cdc6080ad6
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/survey/manager/SurveyManagerImpl.java
@@ -0,0 +1,186 @@
+/**
+ * <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.course.nodes.survey.manager;
+
+import static org.olat.modules.forms.handler.EvaluationFormResource.FORM_XML_FILE;
+
+import java.io.File;
+import java.util.UUID;
+
+import org.olat.core.id.Identity;
+import org.olat.core.util.UserSession;
+import org.olat.course.assessment.CourseAssessmentService;
+import org.olat.course.nodes.SurveyCourseNode;
+import org.olat.course.nodes.survey.SurveyManager;
+import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.fileresource.FileResourceManager;
+import org.olat.modules.assessment.Role;
+import org.olat.modules.assessment.model.AssessmentRunStatus;
+import org.olat.modules.ceditor.DataStorage;
+import org.olat.modules.forms.EvaluationFormManager;
+import org.olat.modules.forms.EvaluationFormParticipation;
+import org.olat.modules.forms.EvaluationFormParticipationIdentifier;
+import org.olat.modules.forms.EvaluationFormSession;
+import org.olat.modules.forms.EvaluationFormSurvey;
+import org.olat.modules.forms.EvaluationFormSurveyIdentifier;
+import org.olat.modules.forms.model.xml.Form;
+import org.olat.repository.RepositoryEntry;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 
+ * Initial date: 10 Sep 2019<br>
+ * 
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+@Service
+public class SurveyManagerImpl implements SurveyManager {
+
+	@Autowired
+	private EvaluationFormManager evaluationFormManager;
+	@Autowired
+	private CourseAssessmentService courseAssessmentService;
+
+	@Override
+	public EvaluationFormSurveyIdentifier getSurveyIdentifier(SurveyCourseNode surveyCourseNode,
+			UserCourseEnvironment userCourseEnv) {
+		RepositoryEntry ores = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		String subIdent = surveyCourseNode.getIdent();
+		return EvaluationFormSurveyIdentifier.of(ores, subIdent);
+	}
+
+	@Override
+	public EvaluationFormSurvey loadSurvey(EvaluationFormSurveyIdentifier surveyIdent) {
+		return evaluationFormManager.loadSurvey(surveyIdent);
+	}
+
+	@Override
+	public EvaluationFormSurvey createSurvey(EvaluationFormSurveyIdentifier surveyIdent, RepositoryEntry formEntry) {
+		return evaluationFormManager.createSurvey(surveyIdent, formEntry);
+	}
+
+	@Override
+	public boolean isFormUpdateable(EvaluationFormSurvey survey) {
+		return evaluationFormManager.isFormUpdateable(survey);
+	}
+
+	@Override
+	public EvaluationFormSurvey updateSurveyForm(EvaluationFormSurvey survey, RepositoryEntry formEntry) {
+		return evaluationFormManager.updateSurveyForm(survey, formEntry);
+	}
+
+	@Override
+	public Form loadForm(EvaluationFormSurvey survey) {
+		RepositoryEntry formEntry = survey.getFormEntry();
+		return evaluationFormManager.loadForm(formEntry);
+	}
+
+	@Override
+	public File getFormFile(EvaluationFormSurvey survey) {
+		RepositoryEntry formEntry = survey.getFormEntry();
+		File repositoryDir = new File(
+				FileResourceManager.getInstance().getFileResourceRoot(formEntry.getOlatResource()),
+				FileResourceManager.ZIPDIR);
+		return new File(repositoryDir, FORM_XML_FILE);
+	}
+
+	@Override
+	public DataStorage loadStorage(EvaluationFormSurvey survey) {
+		RepositoryEntry formEntry = survey.getFormEntry();
+		return evaluationFormManager.loadStorage(formEntry);
+	}
+
+	@Override
+	public EvaluationFormParticipation loadOrCreateGuestParticipation(EvaluationFormSurvey survey, UserSession usess) {
+		String anonymousIdentifier = getAnonymousIdentifier(usess);
+		EvaluationFormParticipationIdentifier identifier = new EvaluationFormParticipationIdentifier("course-node",
+				anonymousIdentifier);
+		return loadOrCreateParticipation(survey, identifier);
+	}
+
+	private String getAnonymousIdentifier(UserSession usess) {
+		String sessionId = usess.getSessionInfo().getSession().getId();
+		Object id = usess.getEntry(sessionId);
+		if (id instanceof String) {
+			return (String) id;
+		}
+
+		String newId = UUID.randomUUID().toString();
+		usess.putEntryInNonClearedStore(sessionId, newId);
+		return newId;
+	}
+
+	public EvaluationFormParticipation loadOrCreateParticipation(EvaluationFormSurvey survey,
+			EvaluationFormParticipationIdentifier identifier) {
+		EvaluationFormParticipation loadedParticipation = evaluationFormManager.loadParticipationByIdentifier(survey, identifier);
+		if (loadedParticipation == null) {
+			loadedParticipation = evaluationFormManager.createParticipation(survey, identifier);
+			loadedParticipation.setAnonymous(true);
+			loadedParticipation = evaluationFormManager.updateParticipation(loadedParticipation);
+		}
+		return loadedParticipation;
+	}
+
+	@Override
+	public EvaluationFormParticipation loadOrCreateParticipation(EvaluationFormSurvey survey, Identity executor) {
+		EvaluationFormParticipation loadedParticipation = evaluationFormManager.loadParticipationByExecutor(survey, executor);
+		if (loadedParticipation == null) {
+			loadedParticipation = evaluationFormManager.createParticipation(survey, executor);
+			loadedParticipation.setAnonymous(true);
+			loadedParticipation = evaluationFormManager.updateParticipation(loadedParticipation);
+		}
+		return loadedParticipation;
+	}
+
+	@Override
+	public EvaluationFormSession loadOrCreateSesssion(EvaluationFormParticipation participation) {
+		EvaluationFormSession session = evaluationFormManager.loadSessionByParticipation(participation);
+		if (session == null) {
+			session = evaluationFormManager.createSession(participation);
+		}
+		return session;
+	}
+
+	@Override
+	public void onExecutionStarted(SurveyCourseNode courseNode, UserCourseEnvironment userCourseEnv) {
+		courseAssessmentService.updateCurrentCompletion(courseNode, userCourseEnv, null, AssessmentRunStatus.running,
+				Role.user);
+	}
+
+	@Override
+	public void onExecutionFinished(SurveyCourseNode courseNode, UserCourseEnvironment userCourseEnv) {
+		courseAssessmentService.incrementAttempts(courseNode, userCourseEnv, Role.user);
+		courseAssessmentService.updateCurrentCompletion(courseNode, userCourseEnv, Double.valueOf(1),
+				AssessmentRunStatus.done, Role.user);
+	}
+
+	@Override
+	public long getCountOfSessions(EvaluationFormSurvey survey) {
+		return evaluationFormManager.getCountOfSessions(survey);
+	}
+
+	@Override
+	public void deleteAllData(EvaluationFormSurvey survey) {
+		evaluationFormManager.deleteAllData(survey);
+	}
+
+}
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyConfigController.java b/src/main/java/org/olat/course/nodes/survey/ui/SurveyConfigController.java
similarity index 89%
rename from src/main/java/org/olat/course/nodes/survey/SurveyConfigController.java
rename to src/main/java/org/olat/course/nodes/survey/ui/SurveyConfigController.java
index 90b2ff566a867251ff2f755749b8618c101cf5d8..47e7de0ff04e9da791ab36740781d974a4562762 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyConfigController.java
+++ b/src/main/java/org/olat/course/nodes/survey/ui/SurveyConfigController.java
@@ -17,9 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.survey;
-
-import static org.olat.modules.forms.handler.EvaluationFormResource.FORM_XML_FILE;
+package org.olat.course.nodes.survey.ui;
 
 import java.io.File;
 import java.util.Collection;
@@ -41,21 +39,18 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
-import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.StringHelper;
-import org.olat.course.ICourse;
 import org.olat.course.editor.NodeEditController;
 import org.olat.course.nodes.SurveyCourseNode;
-import org.olat.fileresource.FileResourceManager;
+import org.olat.course.nodes.survey.SurveyManager;
+import org.olat.course.run.userview.UserCourseEnvironment;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.modules.ceditor.DataStorage;
-import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormSurvey;
 import org.olat.modules.forms.EvaluationFormSurveyIdentifier;
 import org.olat.modules.forms.handler.EvaluationFormResource;
 import org.olat.modules.forms.ui.EvaluationFormExecutionController;
 import org.olat.repository.RepositoryEntry;
-import org.olat.repository.RepositoryManager;
 import org.olat.repository.controllers.ReferencableEntriesSearchController;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -101,22 +96,18 @@ public class SurveyConfigController extends FormBasicController {
 	private LayoutMain3ColsPreviewController previewCtr;
 	
 	private final ModuleConfiguration moduleConfiguration;
-	private final OLATResourceable ores;
-	private final String subIdent;
-	private EvaluationFormSurveyIdentifier surveyIdent;
+	private final EvaluationFormSurveyIdentifier surveyIdent;
 	private EvaluationFormSurvey survey;
 	
 	@Autowired
-	private EvaluationFormManager evaluationFormManager;
+	private SurveyManager surveyManager;
 
-	public SurveyConfigController(UserRequest ureq, WindowControl wControl, ICourse course,
-			SurveyCourseNode surveyCourseNode) {
+	public SurveyConfigController(UserRequest ureq, WindowControl wControl, SurveyCourseNode surveyCourseNode,
+			UserCourseEnvironment userCourseEnv) {
 		super(ureq, wControl);
 		this.moduleConfiguration = surveyCourseNode.getModuleConfiguration();
-		this.ores = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
-		this.subIdent = surveyCourseNode.getIdent();
-		this.surveyIdent = EvaluationFormSurveyIdentifier.of(ores, subIdent);
-		this.survey = evaluationFormManager.loadSurvey(surveyIdent);
+		this.surveyIdent = surveyManager.getSurveyIdentifier(surveyCourseNode, userCourseEnv);
+		this.survey = surveyManager.loadSurvey(surveyIdent);
 		initForm(ureq);
 	}
 
@@ -162,7 +153,7 @@ public class SurveyConfigController extends FormBasicController {
 	}
 
 	private void updateUI() {
-		boolean replacePossible = evaluationFormManager.isFormUpdateable(survey);
+		boolean replacePossible = surveyManager.isFormUpdateable(survey);
 		boolean hasRepoConfig = survey != null;
 		RepositoryEntry formEntry = survey != null? survey.getFormEntry(): null;
 		
@@ -237,11 +228,11 @@ public class SurveyConfigController extends FormBasicController {
 		RepositoryEntry formEntry = searchCtrl.getSelectedEntry();
 		if (formEntry != null) {
 			if (survey == null) {
-				survey = evaluationFormManager.createSurvey(surveyIdent, formEntry);
+				survey = surveyManager.createSurvey(surveyIdent, formEntry);
 			} else {
-				boolean isFormUpdateable = evaluationFormManager.isFormUpdateable(survey);
+				boolean isFormUpdateable = surveyManager.isFormUpdateable(survey);
 				if (isFormUpdateable) {
-					survey = evaluationFormManager.updateSurveyForm(survey, formEntry);
+					survey = surveyManager.updateSurveyForm(survey, formEntry);
 				} else {
 					showError("error.repo.entry.not.replaceable");
 				}
@@ -264,10 +255,8 @@ public class SurveyConfigController extends FormBasicController {
 	}
 
 	private void doPreviewEvaluationForm(UserRequest ureq) {
-		RepositoryEntry formEntry = survey.getFormEntry();
-		File repositoryDir = new File(FileResourceManager.getInstance().getFileResourceRoot(formEntry.getOlatResource()), FileResourceManager.ZIPDIR);
-		File formFile = new File(repositoryDir, FORM_XML_FILE);
-		DataStorage storage = evaluationFormManager.loadStorage(formEntry);
+		File formFile = surveyManager.getFormFile(survey);
+		DataStorage storage = surveyManager.loadStorage(survey);
 		Controller controller = new EvaluationFormExecutionController(ureq, getWindowControl(), formFile, storage);
 
 		previewCtr = new LayoutMain3ColsPreviewController(ureq, getWindowControl(), null,
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyDeleteDataConfirmationController.java b/src/main/java/org/olat/course/nodes/survey/ui/SurveyDeleteDataConfirmationController.java
similarity index 98%
rename from src/main/java/org/olat/course/nodes/survey/SurveyDeleteDataConfirmationController.java
rename to src/main/java/org/olat/course/nodes/survey/ui/SurveyDeleteDataConfirmationController.java
index ca0dd6f2a4424bacc28ae9b2d01b2266792c7930..d2dff8ce746013d536553fee9167698896d0e0db 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyDeleteDataConfirmationController.java
+++ b/src/main/java/org/olat/course/nodes/survey/ui/SurveyDeleteDataConfirmationController.java
@@ -17,7 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.survey;
+package org.olat.course.nodes.survey.ui;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyEditController.java b/src/main/java/org/olat/course/nodes/survey/ui/SurveyEditController.java
similarity index 93%
rename from src/main/java/org/olat/course/nodes/survey/SurveyEditController.java
rename to src/main/java/org/olat/course/nodes/survey/ui/SurveyEditController.java
index 2654d627f3a2d86f469c575d936ed72d2e4120c7..fb5765c2f179d25cb167f69e511b577414c9d720 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyEditController.java
+++ b/src/main/java/org/olat/course/nodes/survey/ui/SurveyEditController.java
@@ -17,7 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.survey;
+package org.olat.course.nodes.survey.ui;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -27,8 +27,8 @@ import org.olat.core.gui.control.ControllerEventListener;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.tabbable.ActivateableTabbableDefaultController;
-import org.olat.course.ICourse;
 import org.olat.course.nodes.SurveyCourseNode;
+import org.olat.course.run.userview.UserCourseEnvironment;
 
 /**
  * 
@@ -46,10 +46,10 @@ public class SurveyEditController extends ActivateableTabbableDefaultController
 	private TabbedPane tabPane;
 	
 	public SurveyEditController(UserRequest ureq, WindowControl wControl, SurveyCourseNode surveyCourseNode,
-			ICourse course) {
+			UserCourseEnvironment userCourseEnv) {
 		super(ureq, wControl);
 		
-		surveyConfigController = new SurveyConfigController(ureq, wControl, course, surveyCourseNode);
+		surveyConfigController = new SurveyConfigController(ureq, wControl, surveyCourseNode, userCourseEnv);
 		listenTo(surveyConfigController);
 	}
 
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyReportingController.java b/src/main/java/org/olat/course/nodes/survey/ui/SurveyReportingController.java
similarity index 88%
rename from src/main/java/org/olat/course/nodes/survey/SurveyReportingController.java
rename to src/main/java/org/olat/course/nodes/survey/ui/SurveyReportingController.java
index d2f1561003fd216f1017709138131fbc53216876..0390897757309ad22968de2c5b97c6f2a491ac7d 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyReportingController.java
+++ b/src/main/java/org/olat/course/nodes/survey/ui/SurveyReportingController.java
@@ -17,7 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.survey;
+package org.olat.course.nodes.survey.ui;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -25,8 +25,8 @@ import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
+import org.olat.course.nodes.survey.SurveyManager;
 import org.olat.modules.ceditor.DataStorage;
-import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormSurvey;
 import org.olat.modules.forms.SessionFilter;
 import org.olat.modules.forms.SessionFilterFactory;
@@ -45,14 +45,14 @@ public class SurveyReportingController extends BasicController {
 	private final VelocityContainer mainVC;
 	
 	@Autowired
-	private EvaluationFormManager evaluationFormManager;
+	private SurveyManager surveyManager;
 
 	public SurveyReportingController(UserRequest ureq, WindowControl wControl, EvaluationFormSurvey survey) {
 		super(ureq, wControl);
 		mainVC = createVelocityContainer("reporting");
 
-		Form form = evaluationFormManager.loadForm(survey.getFormEntry());
-		DataStorage storage = evaluationFormManager.loadStorage(survey.getFormEntry());
+		Form form = surveyManager.loadForm(survey);
+		DataStorage storage = surveyManager.loadStorage(survey);
 		SessionFilter filter = SessionFilterFactory.createSelectDone(survey);
 		EvaluationFormReportsController reportsCtrl = new EvaluationFormReportsController(ureq, wControl, form, storage, filter);
 		mainVC.put("report", reportsCtrl.getInitialComponent());
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyRunController.java b/src/main/java/org/olat/course/nodes/survey/ui/SurveyRunController.java
similarity index 67%
rename from src/main/java/org/olat/course/nodes/survey/SurveyRunController.java
rename to src/main/java/org/olat/course/nodes/survey/ui/SurveyRunController.java
index 6909ddb10069e29376eb57da495efb7645b96e48..a9ad7fcbfe74c2c649f1fdd82aefc340b71cbbed 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyRunController.java
+++ b/src/main/java/org/olat/course/nodes/survey/ui/SurveyRunController.java
@@ -17,11 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.survey;
-
-import static org.olat.modules.forms.EvaluationFormSurveyIdentifier.of;
-
-import java.util.UUID;
+package org.olat.course.nodes.survey.ui;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
@@ -35,20 +31,15 @@ import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
 import org.olat.core.gui.control.generic.messages.MessageUIFactory;
 import org.olat.core.gui.translator.Translator;
-import org.olat.core.id.Identity;
-import org.olat.core.id.OLATResourceable;
-import org.olat.core.util.UserSession;
 import org.olat.core.util.Util;
-import org.olat.course.assessment.CourseAssessmentService;
 import org.olat.course.nodes.SurveyCourseNode;
+import org.olat.course.nodes.survey.SurveyManager;
+import org.olat.course.nodes.survey.SurveyRunSecurityCallback;
 import org.olat.course.run.userview.UserCourseEnvironment;
-import org.olat.modules.assessment.Role;
-import org.olat.modules.assessment.model.AssessmentRunStatus;
-import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormParticipation;
-import org.olat.modules.forms.EvaluationFormParticipationIdentifier;
 import org.olat.modules.forms.EvaluationFormSession;
 import org.olat.modules.forms.EvaluationFormSurvey;
+import org.olat.modules.forms.EvaluationFormSurveyIdentifier;
 import org.olat.modules.forms.ui.EvaluationFormExecutionController;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -69,24 +60,20 @@ public class SurveyRunController extends BasicController {
 	
 	private final UserCourseEnvironment userCourseEnv;
 	private final SurveyCourseNode courseNode;
-	private final OLATResourceable ores;
-	private final String subIdent;
 	private final SurveyRunSecurityCallback secCallback;
+	private final EvaluationFormSurveyIdentifier surveyIdent;
 	private EvaluationFormSurvey survey;
 	private EvaluationFormParticipation participation;
 	
 	@Autowired
-	private EvaluationFormManager evaluationFormManager;
-	@Autowired
-	private CourseAssessmentService courseAssessmentService;
+	private SurveyManager surveyManager;
 
 	public SurveyRunController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv,
 			SurveyCourseNode courseNode, SurveyRunSecurityCallback secCallback) {
 		super(ureq, wControl);
 		this.userCourseEnv = userCourseEnv;
 		this.courseNode = courseNode;
-		this.ores = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
-		this.subIdent = courseNode.getIdent();
+		this.surveyIdent = surveyManager.getSurveyIdentifier(courseNode, userCourseEnv);
 		this.secCallback = secCallback;
 
 		mainVC = createVelocityContainer("run");
@@ -104,7 +91,7 @@ public class SurveyRunController extends BasicController {
 			mainVC.contextPut("withCmds", Boolean.TRUE);
 		}
 		
-		survey = evaluationFormManager.loadSurvey(of(ores, subIdent));
+		survey = surveyManager.loadSurvey(surveyIdent);
 		doShowView(ureq);
 	}
 
@@ -127,52 +114,9 @@ public class SurveyRunController extends BasicController {
 
 	private EvaluationFormParticipation loadOrCreateParticipation(UserRequest ureq) {
 		if (secCallback.isGuestOnly()) {
-			UserSession usess = ureq.getUserSession();
-			String anonymousIdentifier = getAnonymousIdentifier(usess);
-			EvaluationFormParticipationIdentifier identifier = new EvaluationFormParticipationIdentifier("course-node", anonymousIdentifier);
-			return loadOrCreateParticipation(identifier);
-		}
-		return loadOrCreateParticipation(getIdentity());
-	}
-	
-	private String getAnonymousIdentifier(UserSession usess) {
-		String sessionId = usess.getSessionInfo().getSession().getId();
-		Object id = usess.getEntry(sessionId);
-		if (id instanceof String) {
-			return (String) id;
-		}
-
-		String newId = UUID.randomUUID().toString();
-		usess.putEntryInNonClearedStore(sessionId, newId);
-		return newId;
-	}
-
-	private EvaluationFormParticipation loadOrCreateParticipation(EvaluationFormParticipationIdentifier identifier) {
-		EvaluationFormParticipation loadedParticipation = evaluationFormManager.loadParticipationByIdentifier(survey, identifier);
-		if (loadedParticipation == null) {
-			loadedParticipation = evaluationFormManager.createParticipation(survey, identifier);
-			loadedParticipation.setAnonymous(true);
-			loadedParticipation = evaluationFormManager.updateParticipation(loadedParticipation);
-		}
-		return loadedParticipation;
-	}
-
-	private EvaluationFormParticipation loadOrCreateParticipation(Identity executor) {
-		EvaluationFormParticipation loadedParticipation = evaluationFormManager.loadParticipationByExecutor(survey, executor);
-		if (loadedParticipation == null) {
-			loadedParticipation = evaluationFormManager.createParticipation(survey, executor);
-			loadedParticipation.setAnonymous(true);
-			loadedParticipation = evaluationFormManager.updateParticipation(loadedParticipation);
-		}
-		return loadedParticipation;
-	}
-
-	private EvaluationFormSession loadOrCreateSesssion(EvaluationFormParticipation participation) {
-		EvaluationFormSession session = evaluationFormManager.loadSessionByParticipation(participation);
-		if (session == null) {
-			session = evaluationFormManager.createSession(participation);
+			return surveyManager.loadOrCreateGuestParticipation(survey, ureq.getUserSession());
 		}
-		return session;
+		return surveyManager.loadOrCreateParticipation(survey, getIdentity());
 	}
 
 	@Override
@@ -208,20 +152,17 @@ public class SurveyRunController extends BasicController {
 	}
 
 	private void doExecutionFinished(UserRequest ureq) {
-		courseAssessmentService.incrementAttempts(courseNode, userCourseEnv, Role.user);
-		courseAssessmentService.updateCurrentCompletion(courseNode, userCourseEnv, Double.valueOf(1),
-				AssessmentRunStatus.done, Role.user);
+		surveyManager.onExecutionFinished(courseNode, userCourseEnv);
 		doShowView(ureq);
 		fireEvent(ureq, Event.CHANGED_EVENT);
 	}
 
 	private void doQuickSaved() {
-		courseAssessmentService.updateCurrentCompletion(courseNode, userCourseEnv, null, AssessmentRunStatus.running,
-				Role.user);
+		surveyManager.onExecutionStarted(courseNode, userCourseEnv);
 	}
 
 	private void doConfirmDeleteAllData(UserRequest ureq) {
-		long countOfSessions = evaluationFormManager.getCountOfSessions(survey);
+		long countOfSessions = surveyManager.getCountOfSessions(survey);
 		deleteDataConfirmationCtrl = new SurveyDeleteDataConfirmationController(ureq, getWindowControl(), countOfSessions);
 		listenTo(deleteDataConfirmationCtrl);
 		cmc = new CloseableModalController(getWindowControl(), translate("close"),
@@ -231,13 +172,13 @@ public class SurveyRunController extends BasicController {
 	}
 
 	private void doDeleteAllData(UserRequest ureq) {
-		evaluationFormManager.deleteAllData(survey);
+		surveyManager.deleteAllData(survey);
 		initVelocityContainer(ureq);
 	}
 
 	private void doShowExecution(UserRequest ureq) {
 		removeAllComponents();
-		EvaluationFormSession session = loadOrCreateSesssion(participation);
+		EvaluationFormSession session = surveyManager.loadOrCreateSesssion(participation);
 		executionCtrl = new EvaluationFormExecutionController(ureq, getWindowControl(), session);
 		listenTo(executionCtrl);
 		mainVC.put("execution", executionCtrl.getInitialComponent());
diff --git a/src/main/java/org/olat/course/nodes/survey/SurveyStatisticResourceResult.java b/src/main/java/org/olat/course/nodes/survey/ui/SurveyStatisticResourceResult.java
similarity index 96%
rename from src/main/java/org/olat/course/nodes/survey/SurveyStatisticResourceResult.java
rename to src/main/java/org/olat/course/nodes/survey/ui/SurveyStatisticResourceResult.java
index 06b9c5c42b855435179023200c1edea3e9eb32ba..dc36f9538a10c29a4fcc892a70b9dcef12bab773 100644
--- a/src/main/java/org/olat/course/nodes/survey/SurveyStatisticResourceResult.java
+++ b/src/main/java/org/olat/course/nodes/survey/ui/SurveyStatisticResourceResult.java
@@ -17,7 +17,7 @@
  * frentix GmbH, http://www.frentix.com
  * <p>
  */
-package org.olat.course.nodes.survey;
+package org.olat.course.nodes.survey.ui;
 
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
@@ -30,6 +30,7 @@ import org.olat.core.gui.control.generic.messages.SimpleMessageController;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.util.Util;
+import org.olat.course.nodes.survey.SurveyRunSecurityCallback;
 import org.olat.course.statistic.StatisticResourceResult;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormParticipation;
diff --git a/src/main/java/org/olat/course/nodes/survey/_content/delete_data_confirmation.html b/src/main/java/org/olat/course/nodes/survey/ui/_content/delete_data_confirmation.html
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_content/delete_data_confirmation.html
rename to src/main/java/org/olat/course/nodes/survey/ui/_content/delete_data_confirmation.html
diff --git a/src/main/java/org/olat/course/nodes/survey/_content/edit.html b/src/main/java/org/olat/course/nodes/survey/ui/_content/edit.html
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_content/edit.html
rename to src/main/java/org/olat/course/nodes/survey/ui/_content/edit.html
diff --git a/src/main/java/org/olat/course/nodes/survey/_content/reporting.html b/src/main/java/org/olat/course/nodes/survey/ui/_content/reporting.html
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_content/reporting.html
rename to src/main/java/org/olat/course/nodes/survey/ui/_content/reporting.html
diff --git a/src/main/java/org/olat/course/nodes/survey/_content/run.html b/src/main/java/org/olat/course/nodes/survey/ui/_content/run.html
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_content/run.html
rename to src/main/java/org/olat/course/nodes/survey/ui/_content/run.html
diff --git a/src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_de.properties
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_de.properties
rename to src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_de.properties
diff --git a/src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_en.properties
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_en.properties
rename to src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_en.properties
diff --git a/src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_fr.properties
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_fr.properties
rename to src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_fr.properties
diff --git a/src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_pt_BR.properties
similarity index 100%
rename from src/main/java/org/olat/course/nodes/survey/_i18n/LocalStrings_pt_BR.properties
rename to src/main/java/org/olat/course/nodes/survey/ui/_i18n/LocalStrings_pt_BR.properties