diff --git a/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java b/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java
index a3e6859603399ab54d516fc9420fbbc76b9edd67..d06c60b6a825a1f6559cab2d53ba29d5450ccdd5 100644
--- a/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java
+++ b/src/main/java/org/olat/course/archiver/ScoreAccountingHelper.java
@@ -42,6 +42,7 @@ import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.logging.log4j.Logger;
 import org.olat.basesecurity.GroupRoles;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.translator.Translator;
@@ -49,7 +50,6 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.IdentityEnvironment;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.core.id.context.ContextEntry;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
@@ -61,6 +61,7 @@ import org.olat.core.util.openxml.OpenXMLWorksheet.Row;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.manager.UserCourseInformationsManager;
 import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.nodes.ArchiveOptions;
@@ -175,10 +176,11 @@ public class ScoreAccountingHelper {
 			headerRow1.addCell(header1ColCnt++, acNode.getShortTitle());
 			header1ColCnt += acNode.getType().equals("ita") ? 1 : 0;
 			
-			boolean scoreOk = acNode.hasScoreConfigured();
-			boolean passedOk = acNode.hasPassedConfigured();
-			boolean attemptsOk = acNode.hasAttemptsConfigured();
-			boolean commentOk = acNode.hasCommentConfigured();
+			AssessmentConfig assessmentConfig = acNode.getAssessmentConfig();
+			boolean scoreOk = assessmentConfig.hasScoreConfigured();
+			boolean passedOk = assessmentConfig.hasPassedConfigured();
+			boolean attemptsOk = assessmentConfig.hasAttemptsConfigured();
+			boolean commentOk = assessmentConfig.hasCommentConfigured();
 			if (scoreOk || passedOk || commentOk || attemptsOk) {
 				header1ColCnt += scoreOk ? 1 : 0;
 				header1ColCnt += passedOk ? 1 : 0;
@@ -197,10 +199,11 @@ public class ScoreAccountingHelper {
 				headerRow2.addCell(header2ColCnt++, submitted);
 			}
 			
-			boolean scoreOk = acNode.hasScoreConfigured();
-			boolean passedOk = acNode.hasPassedConfigured();
-			boolean attemptsOk = acNode.hasAttemptsConfigured();
-			boolean commentOk = acNode.hasCommentConfigured();
+			AssessmentConfig assessmentConfig = acNode.getAssessmentConfig();
+			boolean scoreOk = assessmentConfig.hasScoreConfigured();
+			boolean passedOk = assessmentConfig.hasPassedConfigured();
+			boolean attemptsOk = assessmentConfig.hasAttemptsConfigured();
+			boolean commentOk = assessmentConfig.hasCommentConfigured();
 			if (scoreOk || passedOk || commentOk || attemptsOk) {
 				if(scoreOk) {
 					headerRow2.addCell(header2ColCnt++, sc);
@@ -259,10 +262,11 @@ public class ScoreAccountingHelper {
 			AssessmentManager am = course.getCourseEnvironment().getAssessmentManager();
 
 			for (AssessableCourseNode acnode:myNodes) {
-				boolean scoreOk = acnode.hasScoreConfigured();
-				boolean passedOk = acnode.hasPassedConfigured();
-				boolean attemptsOk = acnode.hasAttemptsConfigured();
-				boolean commentOk = acnode.hasCommentConfigured();
+				AssessmentConfig assessmentConfig = acnode.getAssessmentConfig();
+				boolean scoreOk = assessmentConfig.hasScoreConfigured();
+				boolean passedOk = assessmentConfig.hasPassedConfigured();
+				boolean attemptsOk = assessmentConfig.hasAttemptsConfigured();
+				boolean commentOk = assessmentConfig.hasCommentConfigured();
 
 				if (acnode.getType().equals("ita")) {
 					String log = acnode.getUserLog(uce);
@@ -348,7 +352,8 @@ public class ScoreAccountingHelper {
 		//min. max. informations
 		boolean first = true;
 		for (AssessableCourseNode acnode:myNodes) {
-			if (!acnode.hasScoreConfigured()) {
+			AssessmentConfig assessmentConfig = acnode.getAssessmentConfig();
+			if (!assessmentConfig.hasScoreConfigured()) {
 				// only show min/max/cut legend when score configured
 				continue;
 			}
@@ -364,15 +369,15 @@ public class ScoreAccountingHelper {
 			String minVal;
 			String maxVal;
 			String cutVal;
-			if(acnode instanceof STCourseNode || !acnode.hasScoreConfigured()) {
+			if(acnode instanceof STCourseNode || !assessmentConfig.hasScoreConfigured()) {
 				minVal = maxVal = cutVal = "-";
 			} else {
-				Float minScoreConfig = acnode.getMinScoreConfiguration();
-				Float maxScoreConfig = acnode.getMaxScoreConfiguration();
+				Float minScoreConfig = assessmentConfig.getMinScoreConfiguration();
+				Float maxScoreConfig = assessmentConfig.getMaxScoreConfiguration();
 				minVal = minScoreConfig == null ? "-" : AssessmentHelper.getRoundedScore(minScoreConfig);
 				maxVal = maxScoreConfig == null ? "-" : AssessmentHelper.getRoundedScore(maxScoreConfig);
-				if (acnode.hasPassedConfigured()) {
-					Float cutValueConfig = acnode.getCutValueConfiguration();
+				if (assessmentConfig.hasPassedConfigured()) {
+					Float cutValueConfig = assessmentConfig.getCutValueConfiguration();
 					cutVal = cutValueConfig == null ? "-" : AssessmentHelper.getRoundedScore(cutValueConfig);
 				} else {
 					cutVal = "-";
diff --git a/src/main/java/org/olat/course/assessment/AssessmentHandler.java b/src/main/java/org/olat/course/assessment/AssessmentHandler.java
deleted file mode 100644
index 792ef0a7eeed10b3e9a12946bc4b0aaddd5f615e..0000000000000000000000000000000000000000
--- a/src/main/java/org/olat/course/assessment/AssessmentHandler.java
+++ /dev/null
@@ -1,171 +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.course.assessment;
-
-import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.components.stack.BreadcrumbPanel;
-import org.olat.core.gui.components.stack.TooledStackedPanel;
-import org.olat.core.gui.control.Controller;
-import org.olat.core.gui.control.WindowControl;
-import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
-import org.olat.course.run.scoring.AssessmentEvaluation;
-import org.olat.course.run.userview.UserCourseEnvironment;
-import org.olat.group.BusinessGroup;
-import org.olat.modules.assessment.ui.AssessmentToolContainer;
-import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback;
-import org.olat.repository.RepositoryEntry;
-
-/**
- * 
- * Initial date: 18 Aug 2019<br>
- * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
- *
- */
-public interface AssessmentHandler {
-	
-	public boolean isAssessedBusinessGroups();
-	
-	/**
-	 * @return Returns the maximal score that can be achieved on this node. Throws 
-	 * an OLATRuntimeException if hasScore set to false, maxScore is undefined in this case
-	 */
-	public Float getMaxScoreConfiguration();
-
-	/**
-	 * @return Returns the minimal score that can be achieved on this node. Throws 
-	 * an OLATRuntimeException if hasScore set to false, maxScore is undefined in this case
-	 */
-	public Float getMinScoreConfiguration();
-
-	/**
-	 * @return Returns the passed cut value or null if no such value is defined. A null
-	 * value means that no cut value is defined and therefore the node can be passed having any 
-	 * score or no score at all. Throws an OLATRuntimeException if hasPassed is set to false, 
-	 * cutValue is undefined in this case
-	 */
-	public Float getCutValueConfiguration();
-	
-	/**
-	 * @return True if this course node produces a score variable for the learner
-	 */
-	public boolean hasScoreConfigured();
-	
-	/**
-	 * @return True if this course node produces a passed variable for the learner
-	 */
-	public boolean hasPassedConfigured();
-	
-	/**
-	 * @return True if this course node produces a comment variable for the learner
-	 */
-	public boolean hasCommentConfigured();
-	
-	/**
-	 * @return True if this course node produces an attempts variable for the learner
-	 */
-	public boolean hasAttemptsConfigured();
-	
-	/**
-	 * 
-	 * @return True if this course node can hold some documents about the assessment of the learner
-	 */
-	public boolean hasIndividualAsssessmentDocuments();
-	
-	
-	/**
-	 * @return True if this course node can produces a completion variable for the learner
-	 */
-	public boolean hasCompletion();
-	
-	/**
-	 * @return True if this course node has additional details to be edited / viewed
-	 */
-	public boolean hasDetails();
-
-	/**
-	 * @return True if score, passed, attempts and comment are editable by the assessment tool
-	 */
-	public boolean isEditableConfigured();
-	
-	/**
-	 * @return True if this course node has additional result details.
-	 */
-	public boolean hasResultsDetails();
-	
-	/**
-	 * @return True if this course node produces an status variable for the learner
-	 */
-	public boolean hasStatusConfigured();
-
-	
-	/**
-	 * this method implementation must not cache any results!
-	 * 
-	 * The user has no scoring results jet (e.g. made no test yet), then the
-	 * ScoreEvaluation.NA has to be returned!
-	 * @param userCourseEnv
-	 * @return null, if this node cannot deliver any useful scoring info (this is not the case for a test never tried or manual scoring: those have default values 0.0f / false for score/passed; currently only the STNode returns null if there are no scoring rules defined.)
-	 */
-	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv);
-	
-	
-	/**
-	 * @param userCourseEnvironment
-	 * @return the details view for this node and this user. will be displayed in 
-	 * the user list. if hasDetails= false this returns null
-	 */	
-	public String getDetailsListView(UserCourseEnvironment userCourseEnvironment);
-	/**
-	 * @return the details list view header key that is used to label the table row
-	 */	
-	public String getDetailsListViewHeaderKey();
-	/**
-	 * Returns a controller to edit the node specific details
-	 * @param ureq
-	 * @param wControl
-	 * @param userCourseEnvironment
-	 * @return a controller or null if hasDetails=false
-	 */
-	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
-			UserCourseEnvironment coachCourseEnv, UserCourseEnvironment assessedUserCourseEnvironment);
-	
-	public Controller getResultDetailsController(UserRequest ureq, WindowControl wControl,
-			UserCourseEnvironment assessedUserCourseEnv);
-	
-	/**
-	 * Returns the controller with the list of assessed identities for
-	 * a specific course node.
-	 * 
-	 * @param ureq
-	 * @param wControl
-	 * @param stackPanel
-	 * @param courseEntry
-	 * @param group
-	 * @param coachCourseEnv
-	 * @param toolContainer
-	 * @param assessmentCallback
-	 * @return
-	 */
-	public AssessmentCourseNodeController getIdentityListController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel,
-			RepositoryEntry courseEntry, BusinessGroup group, UserCourseEnvironment coachCourseEnv,
-			AssessmentToolContainer toolContainer, AssessmentToolSecurityCallback assessmentCallback);
-
-
-}
diff --git a/src/main/java/org/olat/course/assessment/AssessmentHelper.java b/src/main/java/org/olat/course/assessment/AssessmentHelper.java
index d26630daf0faf9dcf9dbd2ce09cc8b66a99cb043..4757667561f9e504dbdeb3c7c7b12ec12c3e7726 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentHelper.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentHelper.java
@@ -47,6 +47,7 @@ import org.olat.core.util.nodes.INode;
 import org.olat.core.util.tree.TreeVisitor;
 import org.olat.core.util.tree.Visitor;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.model.AssessmentNodeData;
 import org.olat.course.assessment.model.AssessmentNodesLastModified;
 import org.olat.course.nodes.AssessableCourseNode;
@@ -156,7 +157,8 @@ public class AssessmentHelper {
 		Integer attempts = null;
 		String details = null;
 		if (courseNode != null) {
-			if (courseNode.hasAttemptsConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if (assessmentConfig.hasAttemptsConfigured()) {
 				attempts = courseNode.getUserAttempts(uce);
 			}
 			if (courseNode.hasDetails()) {
@@ -222,12 +224,14 @@ public class AssessmentHelper {
 		if (node instanceof AssessableCourseNode) {
 			if (node instanceof STCourseNode) {
 				STCourseNode scn = (STCourseNode) node;
-				if (scn.hasPassedConfigured() || scn.hasScoreConfigured()) {
+				AssessmentConfig assessmentConfig = scn.getAssessmentConfig();
+				if (assessmentConfig.hasPassedConfigured() || assessmentConfig.hasScoreConfigured()) {
 					return true;
 				}
 			} else if (node instanceof ScormCourseNode) {
 				ScormCourseNode scormn = (ScormCourseNode) node;
-				if (scormn.hasPassedConfigured() || scormn.hasScoreConfigured()) {
+				AssessmentConfig assessmentConfig = scormn.getAssessmentConfig();
+				if (assessmentConfig.hasPassedConfigured() || assessmentConfig.hasScoreConfigured()) {
 					return true;
 				}
 			} else if (node instanceof ProjectBrokerCourseNode) {
@@ -394,11 +398,12 @@ public class AssessmentHelper {
 		boolean assessable = false;
 		if (courseNode instanceof AssessableCourseNode && !(courseNode instanceof ProjectBrokerCourseNode)) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
 			if (assessableCourseNode.hasDetails()
-				|| assessableCourseNode.hasAttemptsConfigured()
-				|| assessableCourseNode.hasScoreConfigured()
-				|| assessableCourseNode.hasPassedConfigured()
-				|| assessableCourseNode.hasCommentConfigured()) {
+				|| assessmentConfig.hasAttemptsConfigured()
+				|| assessmentConfig.hasScoreConfigured()
+				|| assessmentConfig.hasPassedConfigured()
+				|| assessmentConfig.hasCommentConfigured()) {
 
 				assessable = true;
 			}
@@ -488,6 +493,7 @@ public class AssessmentHelper {
 				assessmentNodeData.setSelectable(false);
 			} else if (courseNode instanceof AssessableCourseNode) {
 				AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
+				AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
 				AssessmentEvaluation scoreEvaluation = scoreAccounting.evalCourseNode(assessableCourseNode);
 				if(scoreEvaluation != null) {
 					assessmentNodeData.setAssessmentStatus(scoreEvaluation.getAssessmentStatus());
@@ -517,7 +523,7 @@ public class AssessmentHelper {
 						}
 					}
 					// attempts
-					if (assessableCourseNode.hasAttemptsConfigured()) {
+					if (assessmentConfig.hasAttemptsConfigured()) {
 						hasDisplayableValuesConfigured = true;
 						Integer attemptsValue = scoreEvaluation.getAttempts(); 
 						if (attemptsValue != null) {
@@ -529,7 +535,7 @@ public class AssessmentHelper {
 						}
 					}
 					// score
-					if (assessableCourseNode.hasScoreConfigured()) {
+					if (assessmentConfig.hasScoreConfigured()) {
 						hasDisplayableValuesConfigured = true;
 						Float score = scoreEvaluation.getScore();
 						if (score != null) {
@@ -538,12 +544,12 @@ public class AssessmentHelper {
 							hasDisplayableUserValues = true;
 						}
 						if(!(assessableCourseNode instanceof STCourseNode)) {
-							assessmentNodeData.setMaxScore(assessableCourseNode.getMaxScoreConfiguration());
-							assessmentNodeData.setMinScore(assessableCourseNode.getMinScoreConfiguration());
+							assessmentNodeData.setMaxScore(assessableCourseNode.getAssessmentConfig().getMaxScoreConfiguration());
+							assessmentNodeData.setMinScore(assessmentConfig.getMinScoreConfiguration());
 						}
 					}
 					// passed
-					if (assessableCourseNode.hasPassedConfigured()) {
+					if (assessmentConfig.hasPassedConfigured()) {
 						hasDisplayableValuesConfigured = true;
 						Boolean passed = scoreEvaluation.getPassed();
 						if (passed != null) {
@@ -553,8 +559,7 @@ public class AssessmentHelper {
 					}
 				}
 				// selection command available
-				AssessableCourseNode acn = (AssessableCourseNode) courseNode;
-				if (acn.isEditableConfigured()) {
+				if (assessmentConfig.isEditableConfigured()) {
 					// Assessable course nodes are selectable
 					assessmentNodeData.setSelectable(true);
 				} else {
@@ -563,7 +568,7 @@ public class AssessmentHelper {
 					assessmentNodeData.setSelectable(false);
 				}
 				
-				if (!hasDisplayableUserValues && assessableCourseNode.hasCommentConfigured() && !discardComments) {
+				if (!hasDisplayableUserValues && assessmentConfig.hasCommentConfigured() && !discardComments) {
 				  // comments are invisible in the table but if configured the node must be in the list
 					// for the efficiency statement this can be ignored, this is the case when discardComments is true
 					hasDisplayableValuesConfigured = true;
diff --git a/src/main/java/org/olat/course/assessment/handler/AssessmentConfig.java b/src/main/java/org/olat/course/assessment/handler/AssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..4927de3b0d233714b444d085f5f893d389f56cc0
--- /dev/null
+++ b/src/main/java/org/olat/course/assessment/handler/AssessmentConfig.java
@@ -0,0 +1,92 @@
+/**
+ * <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.assessment.handler;
+
+/**
+ * 
+ * Initial date: 18 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public interface AssessmentConfig {
+	
+	/**
+	 * @return True if this course node produces a score variable for the learner
+	 */
+	public boolean hasScoreConfigured();
+	
+	/**
+	 * @return Returns the maximal score that can be achieved on this node. Throws 
+	 * an OLATRuntimeException if hasScore set to false, maxScore is undefined in this case
+	 */
+	public Float getMaxScoreConfiguration();
+
+	/**
+	 * @return Returns the minimal score that can be achieved on this node. Throws 
+	 * an OLATRuntimeException if hasScore set to false, maxScore is undefined in this case
+	 */
+	public Float getMinScoreConfiguration();
+	
+	/**
+	 * @return True if this course node produces a passed variable for the learner
+	 */
+	public boolean hasPassedConfigured();
+
+	/**
+	 * @return Returns the passed cut value or null if no such value is defined. A null
+	 * value means that no cut value is defined and therefore the node can be passed having any 
+	 * score or no score at all. Throws an OLATRuntimeException if hasPassed is set to false, 
+	 * cutValue is undefined in this case
+	 */
+	public Float getCutValueConfiguration();
+	
+	/**
+	 * @return True if this course node can produces a completion variable for the learner
+	 */
+	public boolean hasCompletion();
+	
+	/**
+	 * @return True if this course node produces an attempts variable for the learner
+	 */
+	public boolean hasAttemptsConfigured();
+	
+	/**
+	 * @return True if this course node produces a comment variable for the learner
+	 */
+	public boolean hasCommentConfigured();
+	
+	/**
+	 * @return True if this course node can hold some documents about the assessment of the learner
+	 */
+	public boolean hasIndividualAsssessmentDocuments();
+	
+	/**
+	 * @return True if this course node produces an status variable for the learner
+	 */
+	public boolean hasStatusConfigured();
+	
+	public boolean isAssessedBusinessGroups();
+
+	/**
+	 * @return True if score, passed, attempts and comment are editable by the assessment tool
+	 */
+	public boolean isEditableConfigured();
+
+}
diff --git a/src/main/java/org/olat/course/assessment/handler/ModuleAssessmentConfig.java b/src/main/java/org/olat/course/assessment/handler/ModuleAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..d09d2402d82566345565e5571c1cc9ab4022a91f
--- /dev/null
+++ b/src/main/java/org/olat/course/assessment/handler/ModuleAssessmentConfig.java
@@ -0,0 +1,94 @@
+/**
+ * <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.assessment.handler;
+
+import org.olat.core.logging.OLATRuntimeException;
+import org.olat.course.nodes.MSCourseNode;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public abstract class ModuleAssessmentConfig implements AssessmentConfig {
+	
+	protected final ModuleConfiguration config;
+	
+	public ModuleAssessmentConfig(ModuleConfiguration config) {
+		this.config = config;
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
+	}
+
+	@Override
+	public Float getMaxScoreConfiguration() {
+		if (!hasScoreConfigured()) {
+			throw new OLATRuntimeException(ModuleAssessmentConfig.class, "getMaxScore not defined when hasScoreConfigured set to false", null);
+		}
+		return config.getFloatEntry(MSCourseNode.CONFIG_KEY_SCORE_MAX);
+	}
+
+	@Override
+	public Float getMinScoreConfiguration() {
+		if (!hasScoreConfigured()) {
+			throw new OLATRuntimeException(ModuleAssessmentConfig.class, "getMinScore not defined when hasScore set to false", null);
+		}
+		return config.getFloatEntry(MSCourseNode.CONFIG_KEY_SCORE_MIN);
+	}
+	
+	@Override
+	public boolean hasPassedConfigured() {
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD);
+	}
+	
+	@Override
+	public Float getCutValueConfiguration() {
+		if (!hasPassedConfigured()) {
+			throw new OLATRuntimeException(ModuleAssessmentConfig.class, "getCutValue not defined when hasPassed set to false", null);
+		}
+		return config.getFloatEntry(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
+	}
+	
+	@Override
+	public boolean hasCompletion() {
+		return false;
+	}
+
+	@Override
+	public boolean hasCommentConfigured() {
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_COMMENT_FIELD);
+	}
+	
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS);
+	}
+
+	@Override
+	public boolean isAssessedBusinessGroups() {
+		return false;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/assessment/handler/NonAssessmentConfig.java b/src/main/java/org/olat/course/assessment/handler/NonAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..9af738a0036348b20e3e088286bceb32a23ac454
--- /dev/null
+++ b/src/main/java/org/olat/course/assessment/handler/NonAssessmentConfig.java
@@ -0,0 +1,100 @@
+/**
+ * <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.assessment.handler;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class NonAssessmentConfig implements AssessmentConfig {
+	
+	private static final AssessmentConfig INSATNCE = new NonAssessmentConfig();
+	
+	public static final AssessmentConfig create() {
+		return INSATNCE;
+	}
+	
+	private NonAssessmentConfig() {
+		//
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		return false;
+	}
+
+	@Override
+	public Float getMaxScoreConfiguration() {
+		return null;
+	}
+
+	@Override
+	public Float getMinScoreConfiguration() {
+		return null;
+	}
+
+	@Override
+	public boolean hasPassedConfigured() {
+		return false;
+	}
+
+	@Override
+	public Float getCutValueConfiguration() {
+		return null;
+	}
+
+	@Override
+	public boolean hasCompletion() {
+		return false;
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasCommentConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return false;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean isAssessedBusinessGroups() {
+		return false;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java b/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java
index 42d23a33a2c2ddbb12987c12c10ebba6d19324d1..bfcac3c03ba4edf0cd568fdf257752a8c2813266 100644
--- a/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java
+++ b/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java
@@ -73,6 +73,7 @@ import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentLoggingAction;
 import org.olat.course.assessment.AssessmentManager;
 import org.olat.course.assessment.bulk.BulkAssessmentOverviewController;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.model.BulkAssessmentDatas;
 import org.olat.course.assessment.model.BulkAssessmentFeedback;
 import org.olat.course.assessment.model.BulkAssessmentRow;
@@ -310,10 +311,11 @@ public class BulkAssessmentTask implements LongRunnable, TaskAwareRunnable, Sequ
 		final Identity coachIdentity = securityManager.loadIdentityByKey(coachedIdentity);
 		final ICourse course = CourseFactory.loadCourse(courseRes);
 		final AssessableCourseNode courseNode = getCourseNode();
+		final AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
 		
-		final boolean hasUserComment = courseNode.hasCommentConfigured();
-		final boolean hasScore = courseNode.hasScoreConfigured();
-		final boolean hasPassed = courseNode.hasPassedConfigured();
+		final boolean hasUserComment = assessmentConfig.hasCommentConfigured();
+		final boolean hasScore = assessmentConfig.hasScoreConfigured();
+		final boolean hasPassed = assessmentConfig.hasPassedConfigured();
 		final boolean hasReturnFiles = (StringHelper.containsNonWhitespace(datas.getReturnFiles())
 				&& (courseNode instanceof TACourseNode || courseNode instanceof GTACourseNode));
 		
@@ -333,11 +335,11 @@ public class BulkAssessmentTask implements LongRunnable, TaskAwareRunnable, Sequ
 		Float max = null;
 		Float cut = null;
 		if (hasScore) {
-			min = courseNode.getMinScoreConfiguration();
-			max = courseNode.getMaxScoreConfiguration();
+			min = assessmentConfig.getMinScoreConfiguration();
+			max = assessmentConfig.getMaxScoreConfiguration();
 		}
 		if (hasPassed) {
-			cut = courseNode.getCutValueConfiguration();
+			cut = assessmentConfig.getCutValueConfiguration();
 		}
 		
 		int count = 0;
diff --git a/src/main/java/org/olat/course/assessment/model/BulkAssessmentSettings.java b/src/main/java/org/olat/course/assessment/model/BulkAssessmentSettings.java
index 01cdd892d39f0f6eeb02a1dad854989355b62194..f5e072d4d7eb0d564d7b0bde69491ce73a6a8c0c 100644
--- a/src/main/java/org/olat/course/assessment/model/BulkAssessmentSettings.java
+++ b/src/main/java/org/olat/course/assessment/model/BulkAssessmentSettings.java
@@ -22,6 +22,7 @@ package org.olat.course.assessment.model;
 
 import java.io.Serializable;
 
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.ProjectBrokerCourseNode;
@@ -47,9 +48,10 @@ public class BulkAssessmentSettings implements Serializable {
 	private final Float cut;
 
 	public BulkAssessmentSettings(AssessableCourseNode courseNode) {
-		hasUserComment = courseNode.hasCommentConfigured();
-		hasScore = courseNode.hasScoreConfigured();
-		hasPassed = courseNode.hasPassedConfigured();
+		AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+		hasUserComment = assessmentConfig.hasCommentConfigured();
+		hasScore = assessmentConfig.hasScoreConfigured();
+		hasPassed = assessmentConfig.hasPassedConfigured();
 		
 		ModuleConfiguration config = courseNode.getModuleConfiguration();
 		if (courseNode instanceof TACourseNode) {
@@ -66,13 +68,13 @@ public class BulkAssessmentSettings implements Serializable {
 		}
 
 		if (hasScore) {
-			min = courseNode.getMinScoreConfiguration();
-			max = courseNode.getMaxScoreConfiguration();
+			min = assessmentConfig.getMinScoreConfiguration();
+			max = assessmentConfig.getMaxScoreConfiguration();
 		} else {
 			min = max = null;
 		}
 		if (hasPassed) {
-			cut = courseNode.getCutValueConfiguration();
+			cut = assessmentConfig.getCutValueConfiguration();
 		} else {
 			cut = null;
 		}
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessedBusinessGroupCourseNodeListController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessedBusinessGroupCourseNodeListController.java
index af0530f03f8de0b67abbee6e580824019ffd2ca0..860113e43a7e2037ec26c1b8934d6c1b621813f1 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/AssessedBusinessGroupCourseNodeListController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessedBusinessGroupCourseNodeListController.java
@@ -51,6 +51,7 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.assessment.AssessmentModule;
 import org.olat.course.assessment.AssessmentToolManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.model.AssessedBusinessGroup;
 import org.olat.course.assessment.model.SearchAssessedIdentityParams;
 import org.olat.course.assessment.ui.tool.AssessedBusinessGroupTableModel.ABGCols;
@@ -117,11 +118,12 @@ public class AssessedBusinessGroupCourseNodeListController extends FormBasicCont
 		
 		if(courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode aNode = (AssessableCourseNode)courseNode;
-			if(aNode.hasPassedConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if(assessmentConfig.hasPassedConfigured()) {
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ABGCols.countPassed,
 						new ProgressRenderer(false, getTranslator())));
 			}
-			if(aNode.hasScoreConfigured()) {
+			if(assessmentConfig.hasScoreConfigured()) {
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ABGCols.averageScore,
 						new ScoreCellRenderer()));
 			}
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseTreeController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseTreeController.java
index d6b2a05e2d66890b82943202e7075a2006b921d2..b5a0ea0005dd3e9222bead5ef8926a1c62b99c45 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseTreeController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseTreeController.java
@@ -308,7 +308,7 @@ public class AssessmentCourseTreeController extends BasicController implements A
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(oresGroups, null, getWindowControl());
 		OLATResourceable oresNode = OresHelper.createOLATResourceableInstance("Node", Long.valueOf(courseNode.getIdent()));
 		WindowControl bbwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(oresNode, null, bwControl);
-		if(courseNode instanceof AssessableCourseNode && ((AssessableCourseNode)courseNode).isAssessedBusinessGroups()) {
+		if(courseNode instanceof AssessableCourseNode && ((AssessableCourseNode)courseNode).getAssessmentConfig().isAssessedBusinessGroups()) {
 			if(courseNode instanceof GTACourseNode) {
 				CourseEnvironment courseEnv = CourseFactory.loadCourse(courseEntry).getCourseEnvironment();
 				
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java
index 4e6e686eb85738b1d024a83291276e338c8f4b74..3bd4f0a7eec12069f25d942600f6115e92fcce08 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java
@@ -59,6 +59,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentModule;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.run.scoring.ScoreAccounting;
 import org.olat.course.run.scoring.ScoreEvaluation;
@@ -120,11 +121,12 @@ public class AssessmentForm extends FormBasicController {
 		super(ureq, wControl);
 		setTranslator(Util.createPackageTranslator(AssessmentModule.class, getLocale(), getTranslator()));
 		
-		hasAttempts = assessableCourseNode.hasAttemptsConfigured();
-		hasScore = assessableCourseNode.hasScoreConfigured();
-		hasPassed = assessableCourseNode.hasPassedConfigured();
-		hasComment = assessableCourseNode.hasCommentConfigured();
-		hasIndividualAssessmentDocs = assessableCourseNode.hasIndividualAsssessmentDocuments();
+		AssessmentConfig assessmentConfig = assessableCourseNode.getAssessmentConfig();
+		hasAttempts = assessmentConfig.hasAttemptsConfigured();
+		hasScore = assessmentConfig.hasScoreConfigured();
+		hasPassed = assessmentConfig.hasPassedConfigured();
+		hasComment = assessmentConfig.hasCommentConfigured();
+		hasIndividualAssessmentDocs = assessmentConfig.hasIndividualAsssessmentDocuments();
 		
 		this.coachCourseEnv = coachCourseEnv;
 		this.assessedUserCourseEnv = assessedUserCourseEnv;
@@ -496,6 +498,8 @@ public class AssessmentForm extends FormBasicController {
 		setFormTitle("form.title", null);
 		formLayout.setElementCssClass("o_sel_assessment_form");
 		
+		AssessmentConfig assessmentConfig = assessableCourseNode.getAssessmentConfig();
+		
 		ScoreEvaluation scoreEval = assessedUserCourseEnv.getScoreAccounting().evalCourseNode(assessableCourseNode);
 		if (scoreEval == null) {
 			scoreEval = ScoreEvaluation.EMPTY_EVALUATION;
@@ -512,10 +516,10 @@ public class AssessmentForm extends FormBasicController {
 		}
 
 		if (hasScore) {
-			min = assessableCourseNode.getMinScoreConfiguration();
-			max = assessableCourseNode.getMaxScoreConfiguration();
+			min = assessmentConfig.getMinScoreConfiguration();
+			max = assessmentConfig.getMaxScoreConfiguration();
 			if (hasPassed) {
-				cut = assessableCourseNode.getCutValueConfiguration();
+				cut = assessmentConfig.getCutValueConfiguration();
 			}
 			
 			String minStr = AssessmentHelper.getRoundedScore(min);
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java
index 65ad64d781b5f279d12b85c597fbd69a3fc8808d..944ed6757055e3734cc83166a59af479c84c9fa7 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityListCourseTreeController.java
@@ -159,7 +159,7 @@ public class AssessmentIdentityListCourseTreeController extends BasicController
 		OLATResourceable ores = OresHelper.createOLATResourceableInstance("Node", new Long(courseNode.getIdent()));
 		WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl());
 		if(courseNode instanceof AssessableCourseNode) {
-			if(((AssessableCourseNode)courseNode).isAssessedBusinessGroups() && courseNode instanceof GTACourseNode) {
+			if(((AssessableCourseNode)courseNode).getAssessmentConfig().isAssessedBusinessGroups() && courseNode instanceof GTACourseNode) {
 				CourseEnvironment courseEnv = CourseFactory.loadCourse(courseEntry).getCourseEnvironment();
 				
 				List<BusinessGroup> coachedGroups;
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
index a494cee81670b17dfbdf3610fd1538d04afc82f7..5e315f62ab4e850386eedeb138c46f2fa4105d39 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java
@@ -74,6 +74,7 @@ import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentModule;
 import org.olat.course.assessment.AssessmentToolManager;
 import org.olat.course.assessment.bulk.PassedCellRenderer;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.model.SearchAssessedIdentityParams;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeTableModel.IdentityCourseElementCols;
 import org.olat.course.assessment.ui.tool.event.ShowDetailsEvent;
@@ -354,32 +355,33 @@ public class IdentityListCourseNodeController extends FormBasicController
 	protected void initAssessmentColumns(FlexiTableColumnModel columnsModel) {
 		if(courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableNode = (AssessableCourseNode)courseNode;
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
 			
-			if(assessableNode.hasAttemptsConfigured()) {
+			if(assessmentConfig.hasAttemptsConfigured()) {
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.attempts));
 			}
 			if(!(courseNode instanceof CalculatedAssessableCourseNode)) {
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.userVisibility,
 						new UserVisibilityCellRenderer(getTranslator())));
 			}
-			if(assessableNode.hasScoreConfigured()) {
+			if(assessmentConfig.hasScoreConfigured()) {
 				if(!(assessableNode instanceof STCourseNode)) {
-					if(assessableNode.getMinScoreConfiguration() != null) {
+					if(assessmentConfig.getMinScoreConfiguration() != null) {
 						columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.min, new ScoreCellRenderer()));
 					}
-					if(assessableNode.getMaxScoreConfiguration() != null) {
+					if(assessmentConfig.getMaxScoreConfiguration() != null) {
 						columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.max, new ScoreCellRenderer()));
 					}
-					if(assessableNode.hasPassedConfigured() && assessableNode.getCutValueConfiguration() != null) {
+					if(assessmentConfig.hasPassedConfigured() && assessmentConfig.getCutValueConfiguration() != null) {
 						columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.cut, new ScoreCellRenderer()));
 					}
 				}
 				initScoreColumns(columnsModel);
 			}
-			if(assessableNode.hasPassedConfigured()) {
+			if(assessmentConfig.hasPassedConfigured()) {
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.passed, new PassedCellRenderer()));
 			}
-			if(assessableNode.hasIndividualAsssessmentDocuments()) {
+			if(assessmentConfig.hasIndividualAsssessmentDocuments()) {
 				columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.numOfAssessmentDocs));
 			}
 		}
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java
index 20f54440108d3bbdc04cf9ed68b732af67982603..b2d06fd8f34bb3af582970aa3ced60ca148cbbde 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.core.commons.persistence.SortKey;
 import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel;
@@ -31,9 +32,9 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.Filterable
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.certificate.CertificateLight;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.STCourseNode;
@@ -64,12 +65,15 @@ public class IdentityListCourseNodeTableModel extends DefaultFlexiTableDataModel
 		super(columnModel);
 		this.locale = locale;
 		this.courseNode = courseNode;
-		
-		if(courseNode != null && !(courseNode instanceof STCourseNode) && courseNode.hasScoreConfigured()) {
-			maxScore = courseNode.getMaxScoreConfiguration();
-			minScore = courseNode.getMinScoreConfiguration();
-			if (courseNode.hasPassedConfigured()) {
-				cutValue = courseNode.getCutValueConfiguration();
+	
+		if (courseNode != null) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if(!(courseNode instanceof STCourseNode) && assessmentConfig.hasScoreConfigured()) {
+				maxScore = assessmentConfig.getMaxScoreConfiguration();
+				minScore = assessmentConfig.getMinScoreConfiguration();
+				if (assessmentConfig.hasPassedConfigured()) {
+					cutValue = assessmentConfig.getCutValueConfiguration();
+				}
 			}
 		}
 	}
diff --git a/src/main/java/org/olat/course/assessment/ui/tool/tools/AbstractToolsController.java b/src/main/java/org/olat/course/assessment/ui/tool/tools/AbstractToolsController.java
index 5a23115242cfe6548d5c8da4b396984a53e68a31..fdcdf5f76a416caabc94a201598d3aa097c58603 100644
--- a/src/main/java/org/olat/course/assessment/ui/tool/tools/AbstractToolsController.java
+++ b/src/main/java/org/olat/course/assessment/ui/tool/tools/AbstractToolsController.java
@@ -152,7 +152,7 @@ public abstract class AbstractToolsController extends BasicController {
 	}
 	
 	protected void initResetAttempts() {
-		if(courseNode.hasAttemptsConfigured()) {
+		if(courseNode.getAssessmentConfig().hasAttemptsConfigured()) {
 			resetAttemptsButton = addLink("tool.reset.attempts", "reset.attempts", "o_icon o_icon-fw o_icon_reset");
 		}
 	}
diff --git a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
index 4888f8d29ae53c871aa9a700fe0bac4416debfba..48ff4b3d889bbac436b1891688a2057cb617a52e 100644
--- a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java
@@ -51,75 +51,11 @@ import org.olat.repository.RepositoryEntry;
  */
 public interface AssessableCourseNode extends CourseNode {
 	
-	/**
-	 * 
-	 * @return
-	 */
-	public boolean isAssessedBusinessGroups();
-    
-	/**
-	 * @return Returns the maximal score that can be achieved on this node. Throws 
-	 * an OLATRuntimeException if hasScore set to false, maxScore is undefined in this case
-	 */
-	public Float getMaxScoreConfiguration();
-
-	/**
-	 * @return Returns the minimal score that can be achieved on this node. Throws 
-	 * an OLATRuntimeException if hasScore set to false, maxScore is undefined in this case
-	 */
-	public Float getMinScoreConfiguration();
-
-	/**
-	 * @return Returns the passed cut value or null if no such value is defined. A null
-	 * value means that no cut value is definied and therefor the node can be passed having any 
-	 * score or no score at all. Throws an OLATRuntimeException if hasPassed is set to false, 
-	 * cutValue is undefined in this case
-	 */
-	public Float getCutValueConfiguration();
-	
-	/**
-	 * @return True if this course node produces a score variable for the learner
-	 */
-	public boolean hasScoreConfigured();
-	
-	/**
-	 * @return True if this course node produces a passed variable for the learner
-	 */
-	public boolean hasPassedConfigured();
-	
-	/**
-	 * @return True if this course node produces a comment variable for the learner
-	 */
-	public boolean hasCommentConfigured();
-	
-	/**
-	 * @return True if this course node produces an attempts variable for the learner
-	 */
-	public boolean hasAttemptsConfigured();
-	
-	/**
-	 * 
-	 * @return True if this course node can hold some documents about the assessment of the learner
-	 */
-	public boolean hasIndividualAsssessmentDocuments();
-	
-	
-	/**
-	 * @return True if this course node can produces a completion variable for the learner
-	 */
-	public boolean hasCompletion();
-
-	
 	/**
 	 * @return True if this course node has additional details to be edited / viewed
 	 */
 	public boolean hasDetails();
 
-	/**
-	 * @return True if score, passed, attempts and comment are editable by the assessment tool
-	 */
-	public boolean isEditableConfigured();
-	
 	/**
 	 * @return True if this course node has additional result details.
 	 */
@@ -178,10 +114,6 @@ public interface AssessableCourseNode extends CourseNode {
 			AssessmentToolContainer toolContainer, AssessmentToolSecurityCallback assessmentCallback);
 	
 
-	/**
-	 * @return True if this course node produces an status variable for the learner
-	 */
-	public boolean hasStatusConfigured();
 	
 
 }
diff --git a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
index a4865e6c07155b2522316b3cbb69cdf8f5c75e9d..f5e0819a474de47b4f52ffcd14b4a17fbecd5f11 100644
--- a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
+++ b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
@@ -39,16 +39,17 @@ import org.olat.core.gui.control.generic.tabbable.TabbableController;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Roles;
-import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeController;
 import org.olat.course.editor.CourseEditorEnv;
 import org.olat.course.editor.NodeEditController;
 import org.olat.course.editor.StatusDescription;
+import org.olat.course.nodes.basiclti.LTIAssessmentConfig;
 import org.olat.course.nodes.basiclti.LTIConfigForm;
 import org.olat.course.nodes.basiclti.LTIEditController;
 import org.olat.course.nodes.basiclti.LTIRunController;
@@ -274,94 +275,14 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
 		}
 		config.setConfigurationVersion(CURRENT_VERSION);
 	}
-
-	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		if (!hasScoreConfigured()) {
-			throw new OLATRuntimeException(MSCourseNode.class, "getMaxScore not defined when hasScore set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		Float scaleFactor = (Float) config.get(CONFIG_KEY_SCALEVALUE);
-		if(scaleFactor == null || scaleFactor.floatValue() < 0.0000001f) {
-			return 1.0f;
-		}
-		return 1.0f * scaleFactor.floatValue();//LTI 1.1 return between 0.0 - 1.0
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		if (!hasScoreConfigured()) { 
-			throw new OLATRuntimeException(MSCourseNode.class, "getMaxScore not defined when hasScore set to false", null);
-		}
-		return 0.0f;
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		if (!hasPassedConfigured()) { 
-			throw new OLATRuntimeException(MSCourseNode.class, "getCutValue not defined when hasPassed set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		return config.getFloatEntry(CONFIG_KEY_PASSED_CUT_VALUE);
-	}
-
-	@Override
-	public boolean hasScoreConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean score = config.getBooleanEntry(CONFIG_KEY_HAS_SCORE_FIELD);
-		return (score == null) ? false : score.booleanValue();
-	}
-
-	@Override
-	public boolean hasPassedConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean passed = config.getBooleanEntry(CONFIG_KEY_HAS_PASSED_FIELD);
-		return (passed == null) ? false : passed.booleanValue();
-	}
-
-	@Override
-	public boolean hasCommentConfigured() {
-		return false;
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return getModuleConfiguration().getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, false);
-	}
-
-	@Override
-	public boolean hasAttemptsConfigured() {
-		// having score defined means the node is assessable
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean score = config.getBooleanEntry(CONFIG_KEY_HAS_SCORE_FIELD);
-		return (score == null) ? false : score.booleanValue();
-	}
-
-	@Override
-	public boolean hasDetails() {
-		// having score defined means the node is assessable
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean score = config.getBooleanEntry(CONFIG_KEY_HAS_SCORE_FIELD);
-		return (score == null) ? false : score.booleanValue();
-	}
-
-	@Override
-	public boolean hasStatusConfigured() {
-		return false;
-	}
 	
 	@Override
-	public boolean hasCompletion() {
-		return false;
+	public AssessmentConfig getAssessmentConfig() {
+		return new LTIAssessmentConfig(getModuleConfiguration());
 	}
 
 	@Override
-	public boolean isEditableConfigured() {
+	public boolean hasDetails() {
 		// having score defined means the node is assessable
 		ModuleConfiguration config = getModuleConfiguration();
 		Boolean score = config.getBooleanEntry(CONFIG_KEY_HAS_SCORE_FIELD);
diff --git a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
index 6339f7e32db5fa86a1c395a7a4035e3e8a2f5ff7..b6b337f6fa3757af18e6b112df46005a5bf062a9 100644
--- a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java
@@ -45,7 +45,6 @@ import org.olat.core.id.IdentityEnvironment;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.Organisation;
 import org.olat.core.id.Roles;
-import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
@@ -57,6 +56,7 @@ import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeController;
 import org.olat.course.editor.CourseEditorEnv;
@@ -64,6 +64,7 @@ import org.olat.course.editor.NodeEditController;
 import org.olat.course.editor.PublishEvents;
 import org.olat.course.editor.StatusDescription;
 import org.olat.course.export.CourseEnvironmentMapper;
+import org.olat.course.nodes.cl.CheckListAssessmentConfig;
 import org.olat.course.nodes.cl.CheckboxManager;
 import org.olat.course.nodes.cl.model.Checkbox;
 import org.olat.course.nodes.cl.model.CheckboxList;
@@ -166,7 +167,8 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	 */
 	@Override
 	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv) {
-		if(hasPassedConfigured() || hasScoreConfigured()) {
+		AssessmentConfig assessmentConfig = getAssessmentConfig();
+		if(assessmentConfig.hasPassedConfigured() || assessmentConfig.hasScoreConfigured()) {
 			return getUserScoreEvaluation(getUserAssessmentEntry(userCourseEnv));
 		}
 		return AssessmentEvaluation.EMPTY_EVAL;
@@ -269,81 +271,8 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 	}
 	
 	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		if (!hasPassedConfigured()) {
-			throw new OLATRuntimeException(MSCourseNode.class, "getCutValue not defined when hasPassed set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		return (Float)config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		if (!hasScoreConfigured()) {
-			throw new OLATRuntimeException(MSCourseNode.class, "getMaxScore not defined when hasScore set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		return (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX);
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		if (!hasScoreConfigured()) {
-			throw new OLATRuntimeException(MSCourseNode.class, "getMinScore not defined when hasScore set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		return (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MIN);
-	}
-
-	@Override
-	public boolean hasCommentConfigured() {
-		return getModuleConfiguration().getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_COMMENT_FIELD, false);
-	}
-	
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return getModuleConfiguration().getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, false);
-	}
-
-	@Override
-	public boolean hasPassedConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean passed = (Boolean) config.get(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD);
-		if (passed == null) return false;
-		return passed.booleanValue();
-	}
-
-	@Override
-	public boolean hasScoreConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean score = (Boolean)config.get(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
-		if (score == null) return false;
-		return score.booleanValue();
-	}
-
-	@Override
-	public boolean hasStatusConfigured() {
-		return false;
-	}
-
-	@Override
-	public boolean isEditableConfigured() {
-		return true;
-	}
-
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return false;
-	}
-	
-	@Override
-	public boolean hasCompletion() {
-		return false;
+	public AssessmentConfig getAssessmentConfig() {
+		return new CheckListAssessmentConfig(getModuleConfiguration());
 	}
 
 	@Override
@@ -432,7 +361,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
 		new CheckListExcelExport(this, course, locale).exportAll(filename, exportStream);
 		
 		//assessment documents
-		if(hasIndividualAsssessmentDocuments()) {
+		if(getAssessmentConfig().hasIndividualAsssessmentDocuments()) {
 			List<AssessmentEntry> assessmentEntries = course.getCourseEnvironment()
 					.getAssessmentManager().getAssessmentEntries(this);
 			if(assessmentEntries != null && !assessmentEntries.isEmpty()) {
diff --git a/src/main/java/org/olat/course/nodes/CourseNode.java b/src/main/java/org/olat/course/nodes/CourseNode.java
index fe3c547b5cebb8d9ff5b86ef0e42a1a4c37a2a0d..71c7198318d8510a9642fe53b50c07dd977a27a1 100644
--- a/src/main/java/org/olat/course/nodes/CourseNode.java
+++ b/src/main/java/org/olat/course/nodes/CourseNode.java
@@ -40,6 +40,7 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.Organisation;
 import org.olat.core.util.nodes.INode;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.interpreter.ConditionExpression;
 import org.olat.course.condition.interpreter.ConditionInterpreter;
@@ -448,6 +449,8 @@ public interface CourseNode extends INode, ShortName {
 	
 	
 	// Assessment methods
+	
+	public AssessmentConfig getAssessmentConfig();
 
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
 			Identity coachingIdentity, boolean incrementAttempts, Role by);
diff --git a/src/main/java/org/olat/course/nodes/GTACourseNode.java b/src/main/java/org/olat/course/nodes/GTACourseNode.java
index b42169b756ea64b1679670275114c8e6e24dbbe7..f2d14bdd855d5d5ba17e46e06754d1e2b29aba08 100644
--- a/src/main/java/org/olat/course/nodes/GTACourseNode.java
+++ b/src/main/java/org/olat/course/nodes/GTACourseNode.java
@@ -48,7 +48,6 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Organisation;
 import org.olat.core.id.Roles;
-import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.ExportUtil;
 import org.olat.core.util.FileUtils;
@@ -64,6 +63,7 @@ import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.archiver.ScoreAccountingHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.editor.CourseEditorEnv;
 import org.olat.course.editor.NodeEditController;
@@ -71,6 +71,7 @@ import org.olat.course.editor.PublishEvents;
 import org.olat.course.editor.StatusDescription;
 import org.olat.course.export.CourseEnvironmentMapper;
 import org.olat.course.groupsandrights.CourseGroupManager;
+import org.olat.course.nodes.gta.GTAAssessmentConfig;
 import org.olat.course.nodes.gta.GTAManager;
 import org.olat.course.nodes.gta.GTAType;
 import org.olat.course.nodes.gta.Task;
@@ -743,96 +744,16 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi
 		SubscriptionContext subscriptionContext = gtaManager.getSubscriptionContext(course.getCourseEnvironment(), this, false);
 		NotificationsManager.getInstance().delete(subscriptionContext);
 	}
-
+	
 	@Override
-	public boolean isAssessedBusinessGroups() {
-		return GTAType.group.name().equals(getModuleConfiguration().getStringValue(GTACourseNode.GTASK_TYPE));
+	public AssessmentConfig getAssessmentConfig() {
+		return new GTAAssessmentConfig(getModuleConfiguration());
 	}
 	
 	public boolean isOptional() {
 		return getModuleConfiguration().getBooleanSafe(MSCourseNode.CONFIG_KEY_OPTIONAL);
 	}
 
-	@Override
-	public boolean hasStatusConfigured() {
-		return true; // Task Course node has always a status-field
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		if (!hasScoreConfigured()) {
-			throw new OLATRuntimeException(TACourseNode.class, "getMaxScore not defined when hasScore set to false", null);
-		}
-		return getModuleConfiguration().getFloatEntry(MSCourseNode.CONFIG_KEY_SCORE_MAX);
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		if (!hasScoreConfigured()) {
-			throw new OLATRuntimeException(TACourseNode.class, "getMinScore not defined when hasScore set to false", null);
-		}
-		return getModuleConfiguration().getFloatEntry(MSCourseNode.CONFIG_KEY_SCORE_MIN);
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		if (!hasPassedConfigured()) {
-			throw new OLATRuntimeException(TACourseNode.class, "getCutValue not defined when hasPassed set to false", null);
-		}
-		return getModuleConfiguration().getFloatEntry(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
-	}
-
-	@Override
-	public boolean hasScoreConfigured() {
-		boolean hasGrading = getModuleConfiguration().getBooleanSafe(GTASK_GRADING);
-		if (hasGrading) {
-			Boolean score = (Boolean) getModuleConfiguration().get(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
-			if (score != null) {
-				return score.booleanValue();
-			}
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasPassedConfigured() {
-		boolean hasGrading = getModuleConfiguration().getBooleanSafe(GTASK_GRADING);
-		if (hasGrading) {
-			Boolean passed = (Boolean)getModuleConfiguration().get(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD);
-			if (passed != null) {
-				return passed.booleanValue();
-			}
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasCommentConfigured() {
-		boolean hasGrading = getModuleConfiguration().getBooleanSafe(GTASK_GRADING);
-		if (hasGrading) {
-			Boolean comment = (Boolean) getModuleConfiguration().get(MSCourseNode.CONFIG_KEY_HAS_COMMENT_FIELD);
-			if (comment != null) {
-				return comment.booleanValue();
-			}
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		boolean hasGrading = getModuleConfiguration().getBooleanSafe(GTASK_GRADING);
-		if (hasGrading) {
-			return getModuleConfiguration()
-					.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, false);
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasAttemptsConfigured(){
-		return true;
-	}
-
 	@Override
 	public boolean hasDetails() {
 		ModuleConfiguration config =  getModuleConfiguration();
@@ -842,16 +763,6 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi
 				|| config.getBooleanSafe(GTASK_REVISION_PERIOD);
 	}
 	
-	@Override
-	public boolean hasCompletion() {
-		return false;
-	}
-
-	@Override
-	public boolean isEditableConfigured() {
-		return true;
-	}
-	
 	@Override
 	public TabbableController createEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
 			ICourse course, UserCourseEnvironment euce) {
@@ -942,7 +853,8 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi
 
 	@Override
 	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv) {
-		if(hasPassedConfigured() || hasScoreConfigured()) {
+		AssessmentConfig assessmentConfig = getAssessmentConfig();
+		if(assessmentConfig.hasPassedConfigured() || assessmentConfig.hasScoreConfigured()) {
 			return getUserScoreEvaluation(getUserAssessmentEntry(userCourseEnv));
 		}
 		return AssessmentEvaluation.EMPTY_EVAL;
diff --git a/src/main/java/org/olat/course/nodes/GenericCourseNode.java b/src/main/java/org/olat/course/nodes/GenericCourseNode.java
index bd9f673b26c87076dea9db477fd04616c6653f5d..5c752234008809cdffb6f1fd9aa06ba98108f3a3 100644
--- a/src/main/java/org/olat/course/nodes/GenericCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/GenericCourseNode.java
@@ -48,6 +48,8 @@ import org.olat.core.util.nodes.GenericNode;
 import org.olat.core.util.xml.XStreamHelper;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
+import org.olat.course.assessment.handler.NonAssessmentConfig;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.KeyAndNameConverter;
@@ -678,6 +680,13 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod
 		//
 	}
 	
+	// Assessment stuff
+	
+	@Override
+	public AssessmentConfig getAssessmentConfig() {
+		return NonAssessmentConfig.create();
+	}
+	
 	@Override
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment,
 			Identity coachingIdentity, boolean incrementAttempts, Role by) {
@@ -686,7 +695,7 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod
 		am.saveScoreEvaluation(this, coachingIdentity, assessedIdentity, new ScoreEvaluation(scoreEvaluation),
 				userCourseEnvironment, incrementAttempts, by);
 	}
-	
+
 	@Override
 	public Double getUserCurrentRunCompletion(UserCourseEnvironment userCourseEnvironment) {
 		AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
index 3b2c78e303ec66db320b981fcb722c8053eade57..f2221818a7cf676095a2f0f0ce38e4eb84f52cf1 100644
--- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java
@@ -55,6 +55,7 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.course.ICourse;
 import org.olat.course.archiver.ScoreAccountingHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.editor.CourseEditorEnv;
 import org.olat.course.editor.NodeEditController;
@@ -64,6 +65,7 @@ import org.olat.course.nodes.iq.IQEditController;
 import org.olat.course.nodes.iq.IQIdentityListCourseNodeController;
 import org.olat.course.nodes.iq.IQPreviewController;
 import org.olat.course.nodes.iq.IQRunController;
+import org.olat.course.nodes.iq.IQTESTAssessmentConfig;
 import org.olat.course.nodes.iq.QTI21AssessmentRunController;
 import org.olat.course.nodes.iq.QTIResourceTypeModule;
 import org.olat.course.properties.CoursePropertyManager;
@@ -103,7 +105,6 @@ import org.olat.ims.qti21.QTI21Service;
 import org.olat.ims.qti21.manager.AssessmentTestSessionDAO;
 import org.olat.ims.qti21.manager.archive.QTI21ArchiveFormat;
 import org.olat.ims.qti21.model.QTI21StatisticSearchParams;
-import org.olat.ims.qti21.model.xml.QtiNodesExtractor;
 import org.olat.ims.qti21.resultexport.QTI21ResultsExportMediaResource;
 import org.olat.ims.qti21.ui.QTI21AssessmentDetailsController;
 import org.olat.ims.qti21.ui.statistics.QTI21StatisticResourceResult;
@@ -421,130 +422,8 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 	}
 	
 	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		Float cutValue = null;
-		
-		ModuleConfiguration config = getModuleConfiguration();
-		// for onyx and QTI 1.2
-		if (IQEditController.CONFIG_VALUE_QTI2.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))
-				|| IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) {
-			cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE);
-		} else {
-			RepositoryEntry testEntry = getReferencedRepositoryEntry();
-			if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) {
-				AssessmentTest assessmentTest = loadAssessmentTest(testEntry);
-				if(assessmentTest != null) {
-					Double cut = QtiNodesExtractor.extractCutValue(assessmentTest);
-					if(cut != null) {
-						cutValue = Float.valueOf(cut.floatValue());
-					}
-				}
-			} else {
-				cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE);
-			}
-		}
-		return cutValue;
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		Float maxScore = null;
-
-		ModuleConfiguration config = getModuleConfiguration();
-		// for onyx and QTI 1.2
-		if (IQEditController.CONFIG_VALUE_QTI2.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))
-				|| IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) {
-			maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE);
-		} else {
-			RepositoryEntry testEntry = getReferencedRepositoryEntry();
-			if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) {
-				AssessmentTest assessmentTest = loadAssessmentTest(testEntry);
-				if(assessmentTest != null) {
-					Double max = QtiNodesExtractor.extractMaxScore(assessmentTest);
-					if(max != null) {
-						maxScore = Float.valueOf(max.floatValue());
-					}
-				}
-			} else {
-				maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE);
-			}
-		}
-		
-		return maxScore;
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		Float minScore = null;
-		ModuleConfiguration config = getModuleConfiguration();
-		// for onyx and QTI 1.2
-		if (IQEditController.CONFIG_VALUE_QTI2.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))
-				|| IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) {
-			minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE);
-		} else {
-			RepositoryEntry testEntry = getReferencedRepositoryEntry();
-			if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) {
-				AssessmentTest assessmentTest = loadAssessmentTest(testEntry);
-				if(assessmentTest != null) {
-					Double min = QtiNodesExtractor.extractMinScore(assessmentTest);
-					if(min != null) {
-						minScore = Float.valueOf(min.floatValue());
-					}
-				}
-			} else {
-				minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE);
-			}
-		}
-		return minScore;
-	}
-
-	@Override
-	public boolean hasCommentConfigured() {
-		// coach should be able to add comments here, visible to users
-		return true;
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return true;// like user comment
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasPassedConfigured()
-	 */
-	@Override
-	public boolean hasPassedConfigured() {
-		return true;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasScoreConfigured()
-	 */
-	@Override
-	public boolean hasScoreConfigured() {
-		return true;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasStatusConfigured()
-	 */
-	@Override
-	public boolean hasStatusConfigured() {
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#isEditableConfigured()
-	 */
-	@Override
-	public boolean isEditableConfigured() {
-		// test scoring fields can be edited manually
-		return true;
+	public AssessmentConfig getAssessmentConfig() {
+		return new IQTESTAssessmentConfig(this);
 	}
 
 	/**
@@ -697,11 +576,6 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 		}
 	}
 
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return true;
-	}
-
 	public void pullAssessmentTestSession(AssessmentTestSession session, UserCourseEnvironment assessedUserCourseenv, Identity coachingIdentity, Role by) {
 		Boolean visibility;
 		AssessmentEntryStatus assessmentStatus;
@@ -717,12 +591,6 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 		updateUserScoreEvaluation(sceval, assessedUserCourseenv, coachingIdentity, true, by);
 	}
 
-	
-	@Override
-	public boolean hasCompletion() {
-		return IQEditController.CONFIG_VALUE_QTI21.equals(getModuleConfiguration().get(IQEditController.CONFIG_KEY_TYPE_QTI));
-	}
-
 	/**
 	 * @see org.olat.course.nodes.AssessableCourseNode#getDetailsEditController(org.olat.core.gui.UserRequest,
 	 *      org.olat.core.gui.control.WindowControl,
@@ -810,4 +678,9 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
 		}
 	}
 
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return getAssessmentConfig().hasAttemptsConfigured();
+	}
+
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/MSCourseNode.java b/src/main/java/org/olat/course/nodes/MSCourseNode.java
index 325c2d6bb84c0994425854df66410b0e1b1c92b4..cbed7d6609430c688629d3465975ef67628edbad 100644
--- a/src/main/java/org/olat/course/nodes/MSCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/MSCourseNode.java
@@ -52,12 +52,14 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.condition.ConditionEditController;
 import org.olat.course.editor.CourseEditorEnv;
 import org.olat.course.editor.NodeEditController;
 import org.olat.course.editor.PublishEvents;
 import org.olat.course.editor.StatusDescription;
+import org.olat.course.nodes.ms.MSAssessmentConfig;
 import org.olat.course.nodes.ms.MSCourseNodeEditController;
 import org.olat.course.nodes.ms.MSCourseNodeRunController;
 import org.olat.course.nodes.ms.MSEvaluationFormExecutionController;
@@ -277,10 +279,10 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis
 	public static void removeEvaluationFormReference(ModuleConfiguration moduleConfig) {
 		moduleConfig.remove(CONFIG_KEY_EVAL_FORM_SOFTKEY);
 	}
-
 	@Override
 	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv) {
-		if(hasPassedConfigured() || hasScoreConfigured() || hasCommentConfigured()) {
+		AssessmentConfig assessmentConfig = getAssessmentConfig();
+		if(assessmentConfig.hasPassedConfigured() || assessmentConfig.hasScoreConfigured() || assessmentConfig.hasCommentConfigured()) {
 			return getUserScoreEvaluation(getUserAssessmentEntry(userCourseEnv));
 		}
 		return AssessmentEvaluation.EMPTY_EVAL;
@@ -325,58 +327,16 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis
 	}
 
 	@Override
-	public boolean hasCommentConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean comment = (Boolean) config.get(CONFIG_KEY_HAS_COMMENT_FIELD);
-		if (comment == null) return false;
-		return comment.booleanValue();
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return getModuleConfiguration().getBooleanSafe(CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, false);
-	}
-
-	@Override
-	public boolean hasPassedConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean passed = (Boolean) config.get(CONFIG_KEY_HAS_PASSED_FIELD);
-		if (passed == null) return false;
-		return passed.booleanValue();
-	}
-
-	@Override
-	public boolean hasScoreConfigured() {
+	public AssessmentConfig getAssessmentConfig() {
 		updateModuleConfigDefaults(false);
-		ModuleConfiguration config = getModuleConfiguration();
-		String scoreKey = config.getStringValue(CONFIG_KEY_SCORE);
-		return !CONFIG_VALUE_SCORE_NONE.equals(scoreKey);
-	}
-	
-	@Override
-	public boolean hasStatusConfigured() {
-		return false;
+		return new MSAssessmentConfig(getModuleConfiguration());
 	}
 	
-	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		if (!hasScoreConfigured()) { throw new OLATRuntimeException(MSCourseNode.class, "getMaxScore not defined", null); }
-		return getMinMax().getMax();
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		if (!hasScoreConfigured()) { throw new OLATRuntimeException(MSCourseNode.class, "getMinScore not defined", null); }
-		return getMinMax().getMin();
+	private MinMax getMinMax() {
+		return getMinMax(getModuleConfiguration());
 	}
 	
-	private MinMax getMinMax() {
-		ModuleConfiguration config = getModuleConfiguration();
+	public static MinMax getMinMax(ModuleConfiguration config) {
 		String scoreConfig = config.getStringValue(CONFIG_KEY_SCORE);
 		String scaleConfig = config.getStringValue(CONFIG_KEY_EVAL_FORM_SCALE);
 		
@@ -394,30 +354,6 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis
 		return MinMax.of(0.0f,  0.0f);
 	}
 
-	@Override
-	public Float getCutValueConfiguration() {
-		if (!hasPassedConfigured()) { throw new OLATRuntimeException(MSCourseNode.class, "getCutValue not defined when hasPassed set to false", null); }
-		ModuleConfiguration config = getModuleConfiguration();
-		Float cut = (Float) config.get(CONFIG_KEY_PASSED_CUT_VALUE);
-		return cut;
-	}
-
-	@Override
-	public boolean isEditableConfigured() {
-		// manual scoring fields can be edited manually
-		return true;
-	}
-
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return false;
-	}
-
-	@Override
-	public boolean hasCompletion() {
-		return false;
-	}
-
 	@Override
 	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
 			UserCourseEnvironment coachCourseEnv, UserCourseEnvironment assessedUserCourseEnv) {
diff --git a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java
index 56e1a1e6bcb65098f073ce96c87a7822e023536d..30b1d8f73d5b174c2b773e4e98f25a75019106ce 100644
--- a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java
@@ -39,13 +39,13 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Organisation;
 import org.olat.core.id.Roles;
-import org.olat.core.logging.OLATRuntimeException;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.core.util.ValidationStatus;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeController;
 import org.olat.course.condition.Condition;
@@ -54,6 +54,7 @@ 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.portfolio.PortfolioAssessmentConfig;
 import org.olat.course.nodes.portfolio.PortfolioCourseNodeConfiguration;
 import org.olat.course.nodes.portfolio.PortfolioCourseNodeConfiguration.DeadlineType;
 import org.olat.course.nodes.portfolio.PortfolioCourseNodeEditController;
@@ -309,75 +310,8 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements
 	}
 
 	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		if (!hasScoreConfigured()) { 
-			throw new OLATRuntimeException(PortfolioCourseNode.class, "getMaxScore not defined when hasScore set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		Float max = (Float) config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX);
-		return max;
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		if (!hasScoreConfigured()) { 
-			throw new OLATRuntimeException(PortfolioCourseNode.class, "getMinScore not defined when hasScore set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		Float min = (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MIN);
-		return min;
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		if (!hasPassedConfigured()) { 
-			throw new OLATRuntimeException(PortfolioCourseNode.class, "getCutValue not defined when hasPassed set to false", null);
-		}
-		ModuleConfiguration config = getModuleConfiguration();
-		Float cut = (Float) config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
-		return cut;
-	}
-
-	@Override
-	public boolean hasScoreConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean score = (Boolean) config.get(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
-		return (score == null) ? false : score.booleanValue();
-	}
-
-	@Override
-	public boolean hasPassedConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean passed = (Boolean) config.get(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD);
-		return (passed == null) ? false : passed.booleanValue();
-	}
-
-	@Override
-	public boolean hasCommentConfigured() {
-		ModuleConfiguration config = getModuleConfiguration();
-		Boolean comment = (Boolean) config.get(MSCourseNode.CONFIG_KEY_HAS_COMMENT_FIELD);
-		return (comment == null) ? false : comment.booleanValue();
-	}
-	
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return getModuleConfiguration()
-				.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, false);
-	}
-
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return true;
-	}
-
-	@Override
-	public boolean hasCompletion() {
-		return false;
+	public AssessmentConfig getAssessmentConfig() {
+		return new PortfolioAssessmentConfig(getModuleConfiguration());
 	}
 
 	@Override
@@ -385,11 +319,6 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements
 		return true;
 	}
 
-	@Override
-	public boolean isEditableConfigured() {
-		return true;
-	}
-
 	@Override
 	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv) {
 		return getUserScoreEvaluation(getUserAssessmentEntry(userCourseEnv));
@@ -455,11 +384,6 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements
 			UserCourseEnvironment assessedUserCourseEnv) {
 		return null;
 	}
-	
-	@Override
-	public boolean hasStatusConfigured() {
-		return true;
-	}
 
 	@Override
 	public void exportNode(File exportDirectory, ICourse course) {
diff --git a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
index 3d701655f389befbd31aee6eab413b88467b4a41..764eb32ddab3d0f5dbea74c5cbdadf30cc29d1b7 100644
--- a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java
@@ -80,6 +80,7 @@ import org.olat.core.util.vfs.filters.VFSSystemItemFilter;
 import org.olat.core.util.xml.XStreamHelper;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.interpreter.ConditionExpression;
@@ -89,6 +90,7 @@ import org.olat.course.editor.NodeEditController;
 import org.olat.course.editor.StatusDescription;
 import org.olat.course.export.CourseEnvironmentMapper;
 import org.olat.course.nodes.ms.MSEditFormController;
+import org.olat.course.nodes.projectbroker.ProjectBrokerAssessmentConfig;
 import org.olat.course.nodes.projectbroker.ProjectBrokerControllerFactory;
 import org.olat.course.nodes.projectbroker.ProjectBrokerCourseEditorController;
 import org.olat.course.nodes.projectbroker.ProjectBrokerIdentityListCourseNodeController;
@@ -470,6 +472,11 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis
 		condition.setConditionId("projectbroker");
 		this.conditionProjectBroker = condition;
 	}
+	
+	@Override
+	public AssessmentConfig getAssessmentConfig() {
+		return new ProjectBrokerAssessmentConfig(getModuleConfiguration());
+	}
 
 	@Override
 	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv) {
@@ -487,103 +494,6 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis
 		Identity mySelf = userCourseEnv.getIdentityEnvironment().getIdentity();
 		return am.getAssessmentEntry(this, mySelf);
 	}
-	
-	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasCommentConfigured()
-	 */
-	@Override
-	public boolean hasCommentConfigured() {
-		return false;
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasPassedConfigured()
-	 */
-	@Override
-	public boolean hasPassedConfigured() {
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasScoreConfigured()
-	 */
-	@Override
-	public boolean hasScoreConfigured() {
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasStatusConfigured()
-	 */
-	@Override
-	public boolean hasStatusConfigured() {
-		return false; // Project broker Course node has no status-field
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#getMaxScoreConfiguration()
-	 */
-	@Override
-	public Float getMaxScoreConfiguration() {
-		if (!hasScoreConfigured()) { throw new OLATRuntimeException(ProjectBrokerCourseNode.class, "getMaxScore not defined when hasScore set to false", null); }
-		ModuleConfiguration config = getModuleConfiguration();
-		Float max = (Float) config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX);
-		return max;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#getMinScoreConfiguration()
-	 */
-	@Override
-	public Float getMinScoreConfiguration() {
-		if (!hasScoreConfigured()) { throw new OLATRuntimeException(ProjectBrokerCourseNode.class, "getMinScore not defined when hasScore set to false", null); }
-		ModuleConfiguration config = getModuleConfiguration();
-		Float min = (Float) config.get(MSCourseNode.CONFIG_KEY_SCORE_MIN);
-		return min;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#getCutValueConfiguration()
-	 */
-	@Override
-	public Float getCutValueConfiguration() {
-		if (!hasPassedConfigured()) { throw new OLATRuntimeException(ProjectBrokerCourseNode.class, "getCutValue not defined when hasPassed set to false", null); }
-		ModuleConfiguration config = getModuleConfiguration();
-		Float cut = (Float) config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
-		return cut;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#isEditableConfigured()
-	 */
-	@Override
-	public boolean isEditableConfigured() {
-		// always true when assessable
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasAttemptsConfigured()
-	 */
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return false;
-	}
-
-	@Override
-	public boolean hasCompletion() {
-		return false;
-	}
 
 	@Override
 	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
diff --git a/src/main/java/org/olat/course/nodes/STCourseNode.java b/src/main/java/org/olat/course/nodes/STCourseNode.java
index 5d061cd8fd5cab4e854f00ffbaab141f4d5b45d2..6d05464a3f6c91d932993770d2a65d09d7b6508d 100644
--- a/src/main/java/org/olat/course/nodes/STCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/STCourseNode.java
@@ -55,6 +55,7 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.CourseModule;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.KeyAndNameConverter;
@@ -68,6 +69,7 @@ import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.groupsandrights.CourseRights;
 import org.olat.course.nodes.sp.SPEditController;
 import org.olat.course.nodes.sp.SPPeekviewController;
+import org.olat.course.nodes.st.STAssessmentConfig;
 import org.olat.course.nodes.st.STCourseNodeEditController;
 import org.olat.course.nodes.st.STCourseNodeRunController;
 import org.olat.course.nodes.st.STIdentityListCourseNodeController;
@@ -251,6 +253,11 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul
 		}
 	}
 
+	@Override
+	public AssessmentConfig getAssessmentConfig() {
+		return new STAssessmentConfig(getScoreCalculator());
+	}
+
 	/**
 	 * the structure node does not have a score itself, but calculates the
 	 * score/passed info by evaluating the configured expression in the the
@@ -380,74 +387,6 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul
 		failedExpression.setConditionId("failed");
 	}
 
-	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		throw new OLATRuntimeException(STCourseNode.class, "Cut value never defined for ST nodes", null);
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		throw new OLATRuntimeException(STCourseNode.class, "Max score never defined for ST nodes", null);
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		throw new OLATRuntimeException(STCourseNode.class, "Min score never defined for ST nodes", null);
-	}
-
-	@Override
-	public boolean hasCommentConfigured() {
-		// never has comments
-		return false;
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return false;
-	}
-
-	@Override
-	public boolean hasPassedConfigured() {
-		if (scoreCalculator != null && StringHelper.containsNonWhitespace(scoreCalculator.getPassedExpression())) {
-			return true;
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasScoreConfigured() {
-		if (scoreCalculator != null && StringHelper.containsNonWhitespace(scoreCalculator.getScoreExpression())) {
-			return true;
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasStatusConfigured() {
-		return false;
-	}
-
-	@Override
-	public boolean isEditableConfigured() {
-		// ST nodes never editable, data generated on the fly
-		return false;
-	}
-
-	@Override
-	public boolean hasCompletion() {
-		return false;
-	}
-
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return false;
-	}
-
 	@Override
 	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
 			UserCourseEnvironment coachCourseEnv, UserCourseEnvironment assessedUserCourseEnv) {
diff --git a/src/main/java/org/olat/course/nodes/ScormCourseNode.java b/src/main/java/org/olat/course/nodes/ScormCourseNode.java
index b6acecd7da00083e1c80fb63a6ee7d538d269a4c..59275f32edd01a590e32c3feca36ba2ea96f7555 100644
--- a/src/main/java/org/olat/course/nodes/ScormCourseNode.java
+++ b/src/main/java/org/olat/course/nodes/ScormCourseNode.java
@@ -53,12 +53,14 @@ import org.olat.core.util.Util;
 import org.olat.core.util.ZipUtil;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeController;
 import org.olat.course.editor.CourseEditorEnv;
 import org.olat.course.editor.NodeEditController;
 import org.olat.course.editor.StatusDescription;
 import org.olat.course.nodes.cp.CPEditController;
+import org.olat.course.nodes.scorm.ScormAssessmentConfig;
 import org.olat.course.nodes.scorm.ScormEditController;
 import org.olat.course.nodes.scorm.ScormRunController;
 import org.olat.course.properties.CoursePropertyManager;
@@ -372,6 +374,11 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per
 		return true;
 	}
 
+	@Override
+	public AssessmentConfig getAssessmentConfig() {
+		return new ScormAssessmentConfig(getModuleConfiguration());
+	}
+
 	@Override
 	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv) {
 		return getUserScoreEvaluation(getUserAssessmentEntry(userCourseEnv));
@@ -389,91 +396,6 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per
 		return am.getAssessmentEntry(this, mySelf);//we want t
 	}
 
-	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		ModuleConfiguration config = this.getModuleConfiguration();
-		int cutValue = config.getIntegerSafe(ScormEditController.CONFIG_CUTVALUE, 0); 
-		return Float.valueOf(cutValue);
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		// According to SCORM Standard, SCORE is between 0 and 100.
-		return Float.valueOf(100);
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		// According to SCORM Standard, SCORE is between 0 and 100.
-		return Float.valueOf(0);
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasCommentConfigured()
-	 */
-	@Override
-	public boolean hasCommentConfigured() {
-		return false;
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasPassedConfigured()
-	 */
-	@Override
-	public boolean hasPassedConfigured() {
-		return getModuleConfiguration().getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasScoreConfigured()
-	 */
-	@Override
-	public boolean hasScoreConfigured() {
-		boolean assessable = getModuleConfiguration().getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
-		if(assessable) {
-			String type = getModuleConfiguration().getStringValue(ScormEditController.CONFIG_ASSESSABLE_TYPE,
-					ScormEditController.CONFIG_ASSESSABLE_TYPE_SCORE);
-			return ScormEditController.CONFIG_ASSESSABLE_TYPE_SCORE.equals(type);
-		}
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#hasStatusConfigured()
-	 */
-	@Override
-	public boolean hasStatusConfigured() {
-		return false;
-	}
-
-	/**
-	 * @see org.olat.course.nodes.AssessableCourseNode#isEditableConfigured()
-	 */
-	@Override
-	public boolean isEditableConfigured() {
-		return getModuleConfiguration().getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
-	}
-	
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return getModuleConfiguration().getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
-	}
-	
-	@Override
-	public boolean hasCompletion() {
-		return false;
-	}
-
 	@Override
 	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
 			UserCourseEnvironment coachCourseEnv, UserCourseEnvironment assessedUserCourseEnv) {
diff --git a/src/main/java/org/olat/course/nodes/TACourseNode.java b/src/main/java/org/olat/course/nodes/TACourseNode.java
index d30993f9f0f85c447566f8facc8843b2316781aa..d09a7f42bc03abcb70c9e82f79d956d1a19e073f 100644
--- a/src/main/java/org/olat/course/nodes/TACourseNode.java
+++ b/src/main/java/org/olat/course/nodes/TACourseNode.java
@@ -71,6 +71,7 @@ import org.olat.core.util.vfs.filters.VFSSystemItemFilter;
 import org.olat.course.ICourse;
 import org.olat.course.archiver.ScoreAccountingHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.AssessmentCourseNodeController;
 import org.olat.course.condition.Condition;
 import org.olat.course.condition.interpreter.ConditionExpression;
@@ -84,6 +85,7 @@ import org.olat.course.nodes.ta.ConvertToGTACourseNode;
 import org.olat.course.nodes.ta.DropboxController;
 import org.olat.course.nodes.ta.DropboxScoringViewController;
 import org.olat.course.nodes.ta.ReturnboxController;
+import org.olat.course.nodes.ta.TAAssessmentConfig;
 import org.olat.course.nodes.ta.TACourseNodeEditController;
 import org.olat.course.nodes.ta.TACourseNodeRunController;
 import org.olat.course.nodes.ta.TAIdentityListCourseNodeController;
@@ -451,10 +453,16 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa
 		conditionSolution.setConditionId("solution");
 		this.conditionSolution = conditionSolution;
 	}
+	
+	@Override
+	public AssessmentConfig getAssessmentConfig() {
+		return new TAAssessmentConfig(getModuleConfiguration());
+	}
 
 	@Override
 	public AssessmentEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv) {
-		if(hasPassedConfigured() || hasScoreConfigured()) {
+		AssessmentConfig assessmentConfig = getAssessmentConfig();
+		if(assessmentConfig.hasPassedConfigured() || assessmentConfig.hasScoreConfigured()) {
 			return getUserScoreEvaluation(getUserAssessmentEntry(userCourseEnv));
 		}
 		return AssessmentEvaluation.EMPTY_EVAL;
@@ -472,87 +480,6 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa
 		return am.getAssessmentEntry(this, mySelf);
 	}
 
-	@Override
-	public boolean hasCommentConfigured() {
-		Boolean hasScoring = (Boolean) getModuleConfiguration().get(CONF_SCORING_ENABLED);
-		if (hasScoring) {
-			ModuleConfiguration config = getModuleConfiguration();
-			Boolean comment = (Boolean) config.get(MSCourseNode.CONFIG_KEY_HAS_COMMENT_FIELD);
-			if (comment != null) {
-				return comment.booleanValue();
-			}
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasIndividualAsssessmentDocuments() {
-		return false;
-	}
-
-	@Override
-	public boolean hasPassedConfigured() {
-		Boolean hasScoring = (Boolean) getModuleConfiguration().get(CONF_SCORING_ENABLED);
-		if (hasScoring) {
-			ModuleConfiguration config = getModuleConfiguration();
-			Boolean passed = (Boolean) config.get(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD);
-			if (passed != null) {
-				return passed.booleanValue();
-			}
-		}
-		return false;
-	}
-
-	@Override
-	public boolean hasScoreConfigured() {
-		Boolean hasScoring = (Boolean) getModuleConfiguration().get(CONF_SCORING_ENABLED);
-		if (hasScoring) {
-			ModuleConfiguration config = getModuleConfiguration();
-			Boolean score = (Boolean) config.get(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
-			if (score != null) {
-				return score.booleanValue();
-			}
-		}
-		return false;
-	}
-
-	@Override
-	public boolean isAssessedBusinessGroups() {
-		return false;
-	}
-
-	@Override
-	public boolean hasStatusConfigured() {
-		return true; // Task Course node has always a status-field
-	}
-
-	@Override
-	public Float getMaxScoreConfiguration() {
-		if (!hasScoreConfigured()) { throw new OLATRuntimeException(TACourseNode.class, "getMaxScore not defined when hasScore set to false", null); }
-		ModuleConfiguration config = getModuleConfiguration();
-		return (Float) config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX);
-	}
-
-	@Override
-	public Float getMinScoreConfiguration() {
-		if (!hasScoreConfigured()) { throw new OLATRuntimeException(TACourseNode.class, "getMinScore not defined when hasScore set to false", null); }
-		ModuleConfiguration config = getModuleConfiguration();
-		return (Float) config.get(MSCourseNode.CONFIG_KEY_SCORE_MIN);
-	}
-
-	@Override
-	public Float getCutValueConfiguration() {
-		if (!hasPassedConfigured()) { throw new OLATRuntimeException(TACourseNode.class, "getCutValue not defined when hasPassed set to false", null); }
-		ModuleConfiguration config = getModuleConfiguration();
-		return (Float) config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
-	}
-
-	@Override
-	public boolean isEditableConfigured() {
-		// always true
-		return true;
-	}
-
 	@Override
 	//TODO uh anders als die Default Implemntation notwendig?
 	public void updateUserScoreEvaluation(ScoreEvaluation scoreEval, UserCourseEnvironment userCourseEnvironment,
@@ -564,16 +491,6 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa
 		am.saveScoreEvaluation(this, coachingIdentity, mySelf, newScoreEval, userCourseEnvironment, incrementAttempts, by);		
 	}
 
-	@Override
-	public boolean hasAttemptsConfigured() {
-		return true;
-	}
-
-	@Override
-	public boolean hasCompletion() {
-		return false;
-	}
-
 	@Override
 	public Controller getDetailsEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
 			UserCourseEnvironment coachCourseEnv, UserCourseEnvironment assessedUserCourseEnv) {
diff --git a/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java b/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java
index acf944792cad421a8b1a03d67a48ec81db99292d..a9a771ac17e86d7a3442801b995b8eb0b68dc71e 100644
--- a/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java
+++ b/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java
@@ -33,6 +33,7 @@ import org.olat.core.logging.activity.ThreadLocalUserActivityLoggerInstaller;
 import org.olat.core.logging.activity.UserActivityLoggerImpl;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.BasicLTICourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.run.scoring.ScoreEvaluation;
@@ -86,9 +87,10 @@ public class CourseNodeOutcomeMapper extends OutcomeMapper {
 		CourseNode node = course.getRunStructure().getNode(courseNodeId);
 		if(node instanceof BasicLTICourseNode) {
 			BasicLTICourseNode ltiNode = (BasicLTICourseNode)node;
+			AssessmentConfig assessmentConfig = ltiNode.getAssessmentConfig();
 			
 			Identity assessedId = getIdentity();
-			Float cutValue = getCutValue(ltiNode);
+			Float cutValue = getCutValue(assessmentConfig);
 			
 			Float scaledScore = null;
 			Boolean passed = null;
@@ -158,7 +160,7 @@ public class CourseNodeOutcomeMapper extends OutcomeMapper {
 	}
 	
 	private float getScalingFactor(BasicLTICourseNode ltiNode) {
-		if(ltiNode.hasScoreConfigured()) {
+		if(ltiNode.getAssessmentConfig().hasScoreConfigured()) {
 			Float scale = ltiNode.getModuleConfiguration().getFloatEntry(BasicLTICourseNode.CONFIG_KEY_SCALEVALUE);
 			if(scale == null) {
 				return 1.0f;
@@ -168,9 +170,9 @@ public class CourseNodeOutcomeMapper extends OutcomeMapper {
 		return 1.0f;
 	}
 	
-	private Float getCutValue(BasicLTICourseNode ltiNode) {
-		if(ltiNode.hasPassedConfigured()) {
-			Float cutValue = ltiNode.getCutValueConfiguration();
+	private Float getCutValue(AssessmentConfig assessmentConfig) {
+		if(assessmentConfig.hasPassedConfigured()) {
+			Float cutValue = assessmentConfig.getCutValueConfiguration();
 			if(cutValue == null) {
 				return null;
 			}
diff --git a/src/main/java/org/olat/course/nodes/basiclti/LTIAssessmentConfig.java b/src/main/java/org/olat/course/nodes/basiclti/LTIAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ebcbb8fd08b63047f451c200cd14caf559b7560
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/basiclti/LTIAssessmentConfig.java
@@ -0,0 +1,117 @@
+/**
+ * <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.basiclti;
+
+import org.olat.core.logging.OLATRuntimeException;
+import org.olat.course.assessment.handler.AssessmentConfig;
+import org.olat.course.nodes.BasicLTICourseNode;
+import org.olat.course.nodes.MSCourseNode;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class LTIAssessmentConfig implements AssessmentConfig {
+	
+	private final ModuleConfiguration config;
+	
+	public LTIAssessmentConfig(ModuleConfiguration config) {
+		this.config = config;
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
+	}
+
+	@Override
+	public Float getMaxScoreConfiguration() {
+		if (!hasScoreConfigured()) {
+			throw new OLATRuntimeException(LTIAssessmentConfig.class, "getMaxScore not defined when hasScoreConfigured set to false", null);
+		}
+		
+		Float scaleFactor = (Float) config.get(BasicLTICourseNode.CONFIG_KEY_SCALEVALUE);
+		if(scaleFactor == null || scaleFactor.floatValue() < 0.0000001f) {
+			return 1.0f;
+		}
+		return 1.0f * scaleFactor.floatValue();//LTI 1.1 return between 0.0 - 1.0
+	}
+
+	@Override
+	public Float getMinScoreConfiguration() {
+		if (!hasScoreConfigured()) { 
+			throw new OLATRuntimeException(LTIAssessmentConfig.class, "getMaxScore not defined when hasScoreConfigured set to false", null);
+		}
+		return 0.0f;
+	}
+	
+	@Override
+	public boolean hasPassedConfigured() {
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_PASSED_FIELD);
+	}
+	
+	@Override
+	public Float getCutValueConfiguration() {
+		if (!hasPassedConfigured()) { 
+			throw new OLATRuntimeException(LTIAssessmentConfig.class, "getCutValue not defined when hasPassedConfigured set to false", null);
+		}
+		return config.getFloatEntry(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE);
+	}
+	
+	@Override
+	public boolean hasCompletion() {
+		return false;
+	}
+	
+	@Override
+	public boolean hasAttemptsConfigured() {
+		// having score defined means the node is assessable
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
+	}
+	
+	@Override
+	public boolean hasCommentConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_INDIVIDUAL_ASSESSMENT_DOCS, false);
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean isAssessedBusinessGroups() {
+		return false;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		// having score defined means the node is assessable
+		return config.getBooleanSafe(MSCourseNode.CONFIG_KEY_HAS_SCORE_FIELD);
+	}
+}
diff --git a/src/main/java/org/olat/course/nodes/cl/CheckListAssessmentConfig.java b/src/main/java/org/olat/course/nodes/cl/CheckListAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb80d84bca5d244190efe1cf5c980282294aeddf
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/cl/CheckListAssessmentConfig.java
@@ -0,0 +1,52 @@
+/**
+ * <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.cl;
+
+import org.olat.course.assessment.handler.ModuleAssessmentConfig;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class CheckListAssessmentConfig extends ModuleAssessmentConfig {
+
+	public CheckListAssessmentConfig(ModuleConfiguration config) {
+		super(config);
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		return true;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListExcelExport.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListExcelExport.java
index 43c0c36784e4433a5e532f8b9f5ff9a258192d39..d31a9db1e740c4c0b364be0b30e0e26933eed612 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListExcelExport.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListExcelExport.java
@@ -45,6 +45,7 @@ import org.olat.core.util.openxml.OpenXMLWorksheet;
 import org.olat.core.util.openxml.OpenXMLWorksheet.Row;
 import org.olat.core.util.openxml.workbookstyle.CellStyle;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.CheckListCourseNode;
 import org.olat.course.nodes.cl.CheckboxManager;
 import org.olat.course.nodes.cl.model.AssessmentData;
@@ -73,6 +74,8 @@ public class CheckListExcelExport {
 	private Translator translator;
 	private final ICourse course;
 	private final CheckListCourseNode courseNode;
+	private final boolean hasScore;
+	private final boolean hasPassed;
 	private final List<UserPropertyHandler> userPropertyHandlers;
 	
 	private final UserManager userManager;
@@ -81,6 +84,9 @@ public class CheckListExcelExport {
 	public CheckListExcelExport(CheckListCourseNode courseNode, ICourse course, Locale locale) {
 		this.courseNode = courseNode;
 		this.course = course;
+		AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+		this.hasScore = assessmentConfig.hasScoreConfigured();
+		this.hasPassed = assessmentConfig.hasPassedConfigured();
 		
 		userManager = CoreSpringFactory.getImpl(UserManager.class);
 		checkboxManager = CoreSpringFactory.getImpl(CheckboxManager.class);
@@ -134,10 +140,10 @@ public class CheckListExcelExport {
 		header2Row.addCell(col++, translator.translate("column.header.homepage"), headerStyle);
 
 		// course node points and passed
-		if(courseNode.hasScoreConfigured()) {
+		if(hasScore) {
 			header2Row.addCell(col++, translator.translate("column.header.node.points"), headerStyle);
 		}
-		if(courseNode.hasPassedConfigured()) {
+		if(hasPassed) {
 			header2Row.addCell(col++, translator.translate("column.header.node.passed"), headerStyle);
 		}
 
@@ -148,7 +154,7 @@ public class CheckListExcelExport {
 			for(Checkbox checkbox:checkboxList) {
 				String boxTitle = checkbox.getTitle();
 				header2Row.addCell(col++, boxTitle, headerStyle);
-				if(courseNode.hasScoreConfigured() && checkbox.getPoints() != null) {
+				if(hasScore && checkbox.getPoints() != null) {
 					header2Row.addCell(col++, translator.translate("column.header.points"), headerStyle);
 				}	
 			}
@@ -190,14 +196,14 @@ public class CheckListExcelExport {
 		dataRow.addCell(col++, homepage, null);
 		
 		// course node points and passed
-		if(courseNode.hasScoreConfigured()) {
+		if(hasScore) {
 			if(entry != null && entry.getScore() != null) {
 				dataRow.addCell(col++, entry.getScore(), null);
 			} else {
 				col++;
 			}
 		}
-		if(courseNode.hasPassedConfigured()) {
+		if(hasPassed) {
 			if(entry != null && entry.getPassed() != null) {
 				dataRow.addCell(col++, entry.getPassed().toString(), null);
 			} else {
@@ -220,7 +226,7 @@ public class CheckListExcelExport {
 					col++;
 				}
 				
-				if(courseNode.hasScoreConfigured() && checkbox.getPoints() != null) {
+				if(hasScore && checkbox.getPoints() != null) {
 					if(check != null && check.getScore() != null ) {
 						dataRow.addCell(col++, check.getScore(), null);
 					} else {
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java
index 1f4eee48726cab02ccd2048ce8b2278b6ba18920..b129ee9c7c2e153b0405d98bc9fd647bbc2d355c 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java
@@ -55,6 +55,7 @@ import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.highscore.ui.HighScoreRunController;
 import org.olat.course.nodes.CheckListCourseNode;
@@ -207,18 +208,19 @@ public class CheckListRunController extends FormBasicController implements Contr
 			layoutCont.contextPut("comment", null);
 			layoutCont.contextPut("docs", null);
 		} else {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
 			boolean resultsVisible = scoreEval.getUserVisibility() == null || scoreEval.getUserVisibility().booleanValue();
 			layoutCont.contextPut("resultsVisible", resultsVisible);
 			layoutCont.contextPut("score", AssessmentHelper.getRoundedScore(scoreEval.getScore()));
 			layoutCont.contextPut("hasPassedValue", (scoreEval.getPassed() == null ? Boolean.FALSE : Boolean.TRUE));
 			layoutCont.contextPut("passed", scoreEval.getPassed());
 			if(resultsVisible) {
-				if(courseNode.hasCommentConfigured()) {
+				if(assessmentConfig.hasCommentConfigured()) {
 					StringBuilder comment = Formatter.stripTabsAndReturns(scoreEval.getComment());
 					layoutCont.contextPut("comment", StringHelper.xssScan(comment));
 					layoutCont.contextPut("incomment", isPanelOpen(ureq, "comment", true));
 				}
-				if(courseNode.hasIndividualAsssessmentDocuments()) {
+				if(assessmentConfig.hasIndividualAsssessmentDocuments()) {
 					List<File> docs = courseNode.getIndividualAssessmentDocuments(userCourseEnv);
 					String mapperUri = registerCacheableMapper(ureq, null, new DocumentsMapper(docs));
 					layoutCont.contextPut("docsMapperUri", mapperUri);
@@ -337,7 +339,8 @@ public class CheckListRunController extends FormBasicController implements Contr
 		}
 		
 		exposeUserDataToVC(ureq, flc);
-		return courseNode.hasScoreConfigured() || courseNode.hasPassedConfigured();
+		AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+		return assessmentConfig.hasScoreConfigured() || assessmentConfig.hasPassedConfigured();
 	}
 	
 	private void logUpdateCheck(String checkboxId, String boxTitle) {
diff --git a/src/main/java/org/olat/course/nodes/gta/GTAAssessmentConfig.java b/src/main/java/org/olat/course/nodes/gta/GTAAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5ede077e38ff18396e90ebd1ec5f1d0842900aa
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/gta/GTAAssessmentConfig.java
@@ -0,0 +1,89 @@
+/**
+ * <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.gta;
+
+import org.olat.course.assessment.handler.ModuleAssessmentConfig;
+import org.olat.course.nodes.GTACourseNode;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class GTAAssessmentConfig extends ModuleAssessmentConfig {
+
+	private final boolean hasNoGrading;
+
+	public GTAAssessmentConfig(ModuleConfiguration config) {
+		super(config);
+		this.hasNoGrading = !config.getBooleanSafe(GTACourseNode.GTASK_GRADING);
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		if (hasNoGrading) return false;
+		
+		return super.hasScoreConfigured();
+	}
+	
+	@Override
+	public boolean hasPassedConfigured() {
+		if (hasNoGrading) return false;
+		
+		return super.hasPassedConfigured();
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured(){
+		return true;
+	}
+	
+	@Override
+	public boolean hasCommentConfigured() {
+		if (hasNoGrading) return false;
+		
+		return super.hasCommentConfigured();
+	}
+	
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		if (hasNoGrading) return false;
+		
+		return super.hasIndividualAsssessmentDocuments();
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return true; // Task Course node has always a status-field
+	}
+
+	@Override
+	public boolean isAssessedBusinessGroups() {
+		return GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE));
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		return true;
+	}
+	
+}
diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java
index 30aff52104b4ca121d56010e7d89dc1751180b2e..42dabdf0687e320983c69384f2ae725fd3eadcda 100644
--- a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java
+++ b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java
@@ -51,6 +51,7 @@ import org.olat.core.util.vfs.VFSItem;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.GTAManager;
@@ -589,10 +590,11 @@ class GTANotifications {
 			if(resultsVisible) {
 				String score = null;
 				String status = null;
-				if(gtaNode.hasScoreConfigured() && assessment.getScore() != null) {
+				AssessmentConfig assessmentConfig = gtaNode.getAssessmentConfig();
+				if(assessmentConfig.hasScoreConfigured() && assessment.getScore() != null) {
 					score = AssessmentHelper.getRoundedScore(assessment.getScore());
 				}
-				if(gtaNode.hasPassedConfigured() && assessment.getPassed() != null) {
+				if(assessmentConfig.hasPassedConfigured() && assessment.getPassed() != null) {
 					status = assessment.getPassed().booleanValue()
 							? translator.translate("notifications.assessment.passed.true") : translator.translate("notifications.assessment.passed.false");
 				}
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java
index 4bf62cf6b9d2e4532ebb0238e5fb19977648a24e..1345526cac723f2d11cfcbf48a13f79b90ab6c2e 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java
@@ -57,6 +57,7 @@ import org.olat.core.util.Util;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentManager;
 import org.olat.course.assessment.bulk.PassedCellRenderer;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.highscore.ui.HighScoreRunController;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.MSCourseNode;
@@ -133,9 +134,10 @@ public class GTACoachedGroupGradingController extends FormBasicController {
 		this.coachCourseEnv = coachCourseEnv;
 		assessmentManager = courseEnv.getAssessmentManager();
 		
-		withScore = gtaNode.hasScoreConfigured();
-		withPassed = gtaNode.hasPassedConfigured();
-		withComment = gtaNode.hasCommentConfigured();
+		AssessmentConfig assessmentConfig = gtaNode.getAssessmentConfig();
+		withScore = assessmentConfig.hasScoreConfigured();
+		withPassed = assessmentConfig.hasPassedConfigured();
+		withComment = assessmentConfig.hasCommentConfigured();
 		
 		Roles roles = ureq.getUserSession().getRoles();
 		isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles);
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java b/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java
index 138b5778fa363bea334758db435658db85ceeff7..74a37162a4e25df82541a36065f9677571a16762 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java
@@ -57,6 +57,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.gta.GTAManager;
 import org.olat.course.nodes.gta.ui.GroupAssessmentModel.Cols;
@@ -122,12 +123,13 @@ public class GroupAssessmentController extends FormBasicController {
 		this.courseEntry = courseEntry;
 		this.assessedGroup = assessedGroup;
 
-		withScore = courseNode.hasScoreConfigured();
-		withPassed = courseNode.hasPassedConfigured();
+		AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+		withScore = assessmentConfig.hasScoreConfigured();
+		withPassed = assessmentConfig.hasPassedConfigured();
 		if(withPassed) {
-			cutValue = courseNode.getCutValueConfiguration();
+			cutValue = assessmentConfig.getCutValueConfiguration();
 		}
-		withComment = courseNode.hasCommentConfigured();
+		withComment = assessmentConfig.hasCommentConfigured();
 		
 		Roles roles = ureq.getUserSession().getRoles();
 		isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles);
diff --git a/src/main/java/org/olat/course/nodes/iq/IQIdentityListCourseNodeController.java b/src/main/java/org/olat/course/nodes/iq/IQIdentityListCourseNodeController.java
index 73d1c47968ee4d2cdc63ab203ed227bf0d9b6288..fcd383ef66a33ee6c563e5e0ff19b237cf50c304 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQIdentityListCourseNodeController.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQIdentityListCourseNodeController.java
@@ -51,6 +51,7 @@ import org.olat.core.gui.media.MediaResource;
 import org.olat.core.id.Identity;
 import org.olat.course.archiver.ScoreAccountingHelper;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeController;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeTableModel.IdentityCourseElementCols;
 import org.olat.course.assessment.ui.tool.IdentityListCourseNodeToolsController;
@@ -140,7 +141,8 @@ public class IQIdentityListCourseNodeController extends IdentityListCourseNodeCo
 	protected void initStatusColumns(FlexiTableColumnModel columnsModel) {
 		super.initStatusColumns(columnsModel);
 		IQTESTCourseNode testCourseNode = (IQTESTCourseNode)courseNode;
-		if(testCourseNode != null && testCourseNode.hasCompletion()) {
+		AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+		if(testCourseNode != null && assessmentConfig.hasCompletion()) {
 			columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.currentCompletion));
 		}
 		
diff --git a/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java b/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java
index b451ca60f6ce4c30e974be94e1c82360ad2a5667..77ad3dee8cf8c856c55b0f7ae9d32515c8384791 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java
@@ -76,7 +76,7 @@ public class IQPreviewController extends BasicController {
 		if (source == pf) {
 			if (event == Event.DONE_EVENT) {
 				int score = pf.getPointValue();
-				Float cutValue = cn.getCutValueConfiguration();
+				Float cutValue = cn.getAssessmentConfig().getCutValueConfiguration();
 				boolean passed = score >= (cutValue == null ? 0 : cutValue.floatValue());
 				ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), new Boolean(passed));
 				boolean incrementUserAttempts = true;
diff --git a/src/main/java/org/olat/course/nodes/iq/IQRunController.java b/src/main/java/org/olat/course/nodes/iq/IQRunController.java
index a324b1c90c657bd1391e2df67df99da30072568d..d01009068f422323d935a5986ccf28f535f2dc55 100644
--- a/src/main/java/org/olat/course/nodes/iq/IQRunController.java
+++ b/src/main/java/org/olat/course/nodes/iq/IQRunController.java
@@ -71,6 +71,7 @@ import org.olat.course.DisposedCourseRestartController;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.manager.AssessmentNotificationsHandler;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.highscore.ui.HighScoreRunController;
@@ -423,6 +424,7 @@ public class IQRunController extends BasicController implements GenericEventList
 	/**
 	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event)
 	 */
+	@Override
 	public void event(UserRequest ureq, Component source, Event event) {
 		if (source == startButton && startButton.isEnabled() && startButton.isVisible()){
 			long courseResId = userCourseEnv.getCourseEnvironment().getCourseResourceableId().longValue();
@@ -565,6 +567,7 @@ public class IQRunController extends BasicController implements GenericEventList
 	/**
 	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
 	 */
+	@Override
 	public void event(UserRequest urequest, Controller source, Event event) {
 		if (source == displayController) {
 			if (event instanceof IQSubmittedEvent) {
@@ -660,13 +663,14 @@ public class IQRunController extends BasicController implements GenericEventList
 	    		myContent.contextPut("hasPassedValue", (assessmentEntry.getPassed() == null ? Boolean.FALSE : Boolean.TRUE));
 	    		myContent.contextPut("passed", assessmentEntry.getPassed());
 	    		if(resultsVisible) {
-	    			if(acn.hasCommentConfigured()) {
+	    			AssessmentConfig assessmentConfig = acn.getAssessmentConfig();
+	    			if(assessmentConfig.hasCommentConfigured()) {
 	    				StringBuilder comment = Formatter.stripTabsAndReturns(assessmentEntry.getComment());
 	    				myContent.contextPut("comment", StringHelper.xssScan(comment));
 						myContent.contextPut("incomment", isPanelOpen(ureq, "comment", true));
 	    			}
 
-	    			if(acn.hasIndividualAsssessmentDocuments()) {
+	    			if(assessmentConfig.hasIndividualAsssessmentDocuments()) {
 	    				List<File> docs = acn.getIndividualAssessmentDocuments(userCourseEnv);
 						String mapperUri = registerCacheableMapper(ureq, null, new DocumentsMapper(docs));
 						myContent.contextPut("docsMapperUri", mapperUri);
@@ -778,6 +782,7 @@ public class IQRunController extends BasicController implements GenericEventList
 	 * 
 	 * @see org.olat.core.gui.control.DefaultController#doDisspose(boolean)
 	 */
+	@Override
 	protected void doDispose() {
 		// child controllers disposed by basic controller
 		if (!type.equals(AssessmentInstance.QMD_ENTRY_TYPE_ASSESS)) {
diff --git a/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java b/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..89cbd1937806c733d3164cb712e0ad38f6f38d63
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java
@@ -0,0 +1,170 @@
+/**
+ * <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.iq;
+
+import org.olat.course.assessment.handler.AssessmentConfig;
+import org.olat.course.nodes.IQTESTCourseNode;
+import org.olat.ims.qti21.model.xml.QtiNodesExtractor;
+import org.olat.modules.ModuleConfiguration;
+import org.olat.repository.RepositoryEntry;
+
+import uk.ac.ed.ph.jqtiplus.node.test.AssessmentTest;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class IQTESTAssessmentConfig implements AssessmentConfig {
+
+	private final IQTESTCourseNode courseNode;
+
+	public IQTESTAssessmentConfig(IQTESTCourseNode courseNode) {
+		this.courseNode = courseNode;
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		return true;
+	}
+	
+	@Override
+	public Float getMaxScoreConfiguration() {
+		Float maxScore = null;
+
+		ModuleConfiguration config = courseNode.getModuleConfiguration();
+		// for onyx and QTI 1.2
+		if (IQEditController.CONFIG_VALUE_QTI2.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))
+				|| IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) {
+			maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE);
+		} else {
+			RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry();
+			if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) {
+				AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry);
+				if(assessmentTest != null) {
+					Double max = QtiNodesExtractor.extractMaxScore(assessmentTest);
+					if(max != null) {
+						maxScore = Float.valueOf(max.floatValue());
+					}
+				}
+			} else {
+				maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE);
+			}
+		}
+		
+		return maxScore;
+	}
+
+
+	@Override
+	public Float getMinScoreConfiguration() {
+		Float minScore = null;
+		ModuleConfiguration config = courseNode.getModuleConfiguration();
+		// for onyx and QTI 1.2
+		if (IQEditController.CONFIG_VALUE_QTI2.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))
+				|| IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) {
+			minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE);
+		} else {
+			RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry();
+			if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) {
+				AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry);
+				if(assessmentTest != null) {
+					Double min = QtiNodesExtractor.extractMinScore(assessmentTest);
+					if(min != null) {
+						minScore = Float.valueOf(min.floatValue());
+					}
+				}
+			} else {
+				minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE);
+			}
+		}
+		return minScore;
+	}
+	
+	@Override
+	public boolean hasPassedConfigured() {
+		return true;
+	}
+
+	@Override
+	public Float getCutValueConfiguration() {
+		Float cutValue = null;
+		
+		ModuleConfiguration config = courseNode.getModuleConfiguration();
+		// for onyx and QTI 1.2
+		if (IQEditController.CONFIG_VALUE_QTI2.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))
+				|| IQEditController.CONFIG_VALUE_QTI1.equals(config.get(IQEditController.CONFIG_KEY_TYPE_QTI))) {
+			cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE);
+		} else {
+			RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry();
+			if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) {
+				AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry);
+				if(assessmentTest != null) {
+					Double cut = QtiNodesExtractor.extractCutValue(assessmentTest);
+					if(cut != null) {
+						cutValue = Float.valueOf(cut.floatValue());
+					}
+				}
+			} else {
+				cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE);
+			}
+		}
+		return cutValue;
+	}
+	
+	@Override
+	public boolean hasCompletion() {
+		return IQEditController.CONFIG_VALUE_QTI21.equals(courseNode.getModuleConfiguration().get(IQEditController.CONFIG_KEY_TYPE_QTI));
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return true;
+	}
+	
+	@Override
+	public boolean hasCommentConfigured() {
+		// coach should be able to add comments here, visible to users
+		return true;
+	}
+
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return true;// like user comment
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean isAssessedBusinessGroups() {
+		return false;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		// test scoring fields can be edited manually
+		return true;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
index 7de22e0bec5e4afe43a0568aa180f32efe81d2ef..319846a334f2b9f0b4f50ae5b6c650f5cf301617 100644
--- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
+++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java
@@ -61,6 +61,7 @@ import org.olat.course.CourseModule;
 import org.olat.course.DisposedCourseRestartController;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.manager.AssessmentNotificationsHandler;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.highscore.ui.HighScoreRunController;
@@ -241,7 +242,8 @@ public class QTI21AssessmentRunController extends BasicController implements Gen
 
 		if (courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
-			if (assessableCourseNode.hasScoreConfigured() || userCourseEnv.isCoach()){
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if (assessmentConfig.hasScoreConfigured() || userCourseEnv.isCoach()){
 				HighScoreRunController highScoreCtr = new HighScoreRunController(ureq, getWindowControl(), userCourseEnv, courseNode);
 				if (highScoreCtr.isViewHighscore()) {
 					Component highScoreComponent = highScoreCtr.getInitialComponent();
@@ -294,7 +296,8 @@ public class QTI21AssessmentRunController extends BasicController implements Gen
 				mainVC.contextPut("hasPassedValue", (passed == null ? Boolean.FALSE : Boolean.TRUE));
 				mainVC.contextPut("passed", passed);
 				if(resultsVisible) {
-					if(testCourseNode.hasCommentConfigured()) {
+					AssessmentConfig assessmentConfig = testCourseNode.getAssessmentConfig();
+					if(assessmentConfig.hasCommentConfigured()) {
 						StringBuilder comment = Formatter.stripTabsAndReturns(testCourseNode.getUserComment(userCourseEnv));
 						if (comment != null && comment.length() > 0) {
 							mainVC.contextPut("comment", StringHelper.xssScan(comment));
@@ -302,7 +305,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen
 						}
 					}
 					
-					if(testCourseNode.hasIndividualAsssessmentDocuments()) {
+					if(assessmentConfig.hasIndividualAsssessmentDocuments()) {
 						List<File> docs = testCourseNode.getIndividualAssessmentDocuments(userCourseEnv);
 						String mapperUri = registerCacheableMapper(ureq, null, new DocumentsMapper(docs));
 						mainVC.contextPut("docsMapperUri", mapperUri);
diff --git a/src/main/java/org/olat/course/nodes/ms/MSAssessmentConfig.java b/src/main/java/org/olat/course/nodes/ms/MSAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..ccbad226fdd6ca23402a0f65f35b340cbeff05a8
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/ms/MSAssessmentConfig.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.course.nodes.ms;
+
+import org.olat.core.logging.OLATRuntimeException;
+import org.olat.course.assessment.handler.ModuleAssessmentConfig;
+import org.olat.course.nodes.MSCourseNode;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class MSAssessmentConfig extends ModuleAssessmentConfig {
+
+	public MSAssessmentConfig(ModuleConfiguration config) {
+		super(config);
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		String scoreKey = config.getStringValue(MSCourseNode.CONFIG_KEY_SCORE);
+		return !MSCourseNode.CONFIG_VALUE_SCORE_NONE.equals(scoreKey);
+	}
+	
+	@Override
+	public Float getMaxScoreConfiguration() {
+		if (!hasScoreConfigured()) {
+			throw new OLATRuntimeException(MSAssessmentConfig.class, "getMaxScore not defined when hasScoreConfigured set to false", null);
+		}
+		return MSCourseNode.getMinMax(config).getMax();
+	}
+	
+	@Override
+	public Float getMinScoreConfiguration() {
+		if (!hasScoreConfigured()) {
+			throw new OLATRuntimeException(MSAssessmentConfig.class, "getMinScore not defined when hasScoreConfigured set to false", null);
+		}
+		return MSCourseNode.getMinMax(config).getMin();
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		// manual scoring fields can be edited manually
+		return true;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/nodes/ms/MSCourseNodeEditController.java b/src/main/java/org/olat/course/nodes/ms/MSCourseNodeEditController.java
index 1aa03a63078db78de29c0d975ac0c2d3c340a9ca..e60f0e7bf7b3997c7d132b8d0c32856f738a25cb 100644
--- a/src/main/java/org/olat/course/nodes/ms/MSCourseNodeEditController.java
+++ b/src/main/java/org/olat/course/nodes/ms/MSCourseNodeEditController.java
@@ -139,7 +139,7 @@ public class MSCourseNodeEditController extends ActivateableTabbableDefaultContr
 	}
 	
 	private void updateHighscoreTab() {
-		myTabbedPane.setEnabled(4, msNode.hasScoreConfigured());
+		myTabbedPane.setEnabled(4, msNode.getAssessmentConfig().hasScoreConfigured());
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/course/nodes/ms/MSCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/ms/MSCourseNodeRunController.java
index bc647aef73e47275b829096c48ad4e0e6e87a6e5..ded647281c17ff478c19d01677373ea96106ab21 100644
--- a/src/main/java/org/olat/course/nodes/ms/MSCourseNodeRunController.java
+++ b/src/main/java/org/olat/course/nodes/ms/MSCourseNodeRunController.java
@@ -46,6 +46,7 @@ import org.olat.core.util.Util;
 import org.olat.core.util.prefs.Preferences;
 import org.olat.course.CourseModule;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.auditing.UserNodeAuditManager;
 import org.olat.course.highscore.ui.HighScoreRunController;
 import org.olat.course.nodes.CourseNode;
@@ -192,17 +193,18 @@ public class MSCourseNodeRunController extends BasicController implements Activa
 	}
 	
 	private void exposeConfigToVC(UserRequest ureq) {
+		AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
 		ModuleConfiguration config = courseNode.getModuleConfiguration();
-		myContent.contextPut("hasScoreField", courseNode.hasScoreConfigured());
-		if (courseNode.hasScoreConfigured()) {
-			myContent.contextPut("scoreMin", AssessmentHelper.getRoundedScore(courseNode.getMinScoreConfiguration()));
-			myContent.contextPut("scoreMax", AssessmentHelper.getRoundedScore(courseNode.getMaxScoreConfiguration()));
+		myContent.contextPut("hasScoreField", assessmentConfig.hasScoreConfigured());
+		if (assessmentConfig.hasScoreConfigured()) {
+			myContent.contextPut("scoreMin", AssessmentHelper.getRoundedScore(assessmentConfig.getMinScoreConfiguration()));
+			myContent.contextPut("scoreMax", AssessmentHelper.getRoundedScore(assessmentConfig.getMaxScoreConfiguration()));
 		}
-		myContent.contextPut("hasPassedField", courseNode.hasPassedConfigured());
-		if (courseNode.hasPassedConfigured()) {
-			myContent.contextPut("passedCutValue", AssessmentHelper.getRoundedScore(courseNode.getCutValueConfiguration()));
+		myContent.contextPut("hasPassedField", assessmentConfig.hasPassedConfigured());
+		if (assessmentConfig.hasPassedConfigured()) {
+			myContent.contextPut("passedCutValue", AssessmentHelper.getRoundedScore(assessmentConfig.getCutValueConfiguration()));
 		}
-		myContent.contextPut("hasCommentField", courseNode.hasCommentConfigured());
+		myContent.contextPut("hasCommentField", assessmentConfig.hasCommentConfigured());
 		String infoTextUser = (String) config.get(MSCourseNode.CONFIG_KEY_INFOTEXT_USER);
 		if(StringHelper.containsNonWhitespace(infoTextUser)) {
 				myContent.contextPut(MSCourseNode.CONFIG_KEY_INFOTEXT_USER, infoTextUser);
@@ -220,7 +222,8 @@ public class MSCourseNodeRunController extends BasicController implements Activa
 			String rawComment = assessmentEntry.getComment();
 			hasPassed = assessmentEntry.getPassed() != null;
 			hasScore = assessmentEntry.getScore() != null;
-			hasComment = courseNode.hasCommentConfigured() && StringHelper.containsNonWhitespace(rawComment);
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			hasComment = assessmentConfig.hasCommentConfigured() && StringHelper.containsNonWhitespace(rawComment);
 		
 			boolean resultsVisible = overrideUserResultsVisiblity
 					|| assessmentEntry.getUserVisibility() == null
@@ -237,7 +240,7 @@ public class MSCourseNodeRunController extends BasicController implements Activa
 					myContent.contextPut("incomment", isPanelOpen(ureq, "comment", true));
 				}
 				
-				if(courseNode.hasIndividualAsssessmentDocuments()) {
+				if(assessmentConfig.hasIndividualAsssessmentDocuments()) {
 					List<File> docs = courseNode.getIndividualAssessmentDocuments(userCourseEnv);
 					mapperUri = registerCacheableMapper(ureq, null, new DocumentsMapper(docs));
 					myContent.contextPut("docsMapperUri", mapperUri);
diff --git a/src/main/java/org/olat/course/nodes/portfolio/PortfolioAssessmentConfig.java b/src/main/java/org/olat/course/nodes/portfolio/PortfolioAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..41cd031121696325d5a9fb9bc84424a142da0f2d
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/portfolio/PortfolioAssessmentConfig.java
@@ -0,0 +1,52 @@
+/**
+ * <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.portfolio;
+
+import org.olat.course.assessment.handler.ModuleAssessmentConfig;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class PortfolioAssessmentConfig extends ModuleAssessmentConfig {
+
+	public PortfolioAssessmentConfig(ModuleConfiguration config) {
+		super(config);
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return true;
+	}
+	
+	@Override
+	public boolean hasStatusConfigured() {
+		return true;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		return true;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java
index d1243452866b08b13a792c698ac4427993f709ad..dd5577613545d0433cc2fde99eca1eedb1e9bbb3 100644
--- a/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java
+++ b/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java
@@ -52,6 +52,7 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.course.CourseModule;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.assessment.AssessmentManager;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.highscore.ui.HighScoreRunController;
 import org.olat.course.nodes.MSCourseNode;
 import org.olat.course.nodes.PortfolioCourseNode;
@@ -308,40 +309,42 @@ public class PortfolioCourseNodeRunController extends FormBasicController {
 			ScoreAccounting scoreAccounting = userCourseEnv.getScoreAccounting();
 			scoreAccounting.evaluateAll();			
 			ScoreEvaluation scoreEval = scoreAccounting.evalCourseNode(courseNode);
-
+			
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			
 			boolean resultsVisible = scoreEval.getUserVisible() == null || scoreEval.getUserVisible().booleanValue();
 			assessmentInfosContainer.contextPut("resultsVisible", resultsVisible);
 			//score
-			assessmentInfosContainer.contextPut("hasScoreField", new Boolean(courseNode.hasScoreConfigured()));
-			if(courseNode.hasScoreConfigured()) {
+			assessmentInfosContainer.contextPut("hasScoreField", new Boolean(assessmentConfig.hasScoreConfigured()));
+			if(assessmentConfig.hasScoreConfigured()) {
 				Float score = scoreEval.getScore();
-				Float minScore = courseNode.getMinScoreConfiguration();
-				Float maxScore = courseNode.getMaxScoreConfiguration();
+				Float minScore = assessmentConfig.getMinScoreConfiguration();
+				Float maxScore = assessmentConfig.getMaxScoreConfiguration();
 				assessmentInfosContainer.contextPut("scoreMin", AssessmentHelper.getRoundedScore(minScore));
 				assessmentInfosContainer.contextPut("scoreMax", AssessmentHelper.getRoundedScore(maxScore));
 				assessmentInfosContainer.contextPut("score", AssessmentHelper.getRoundedScore(score));
 			}
 
 			//passed
-			assessmentInfosContainer.contextPut("hasPassedField", new Boolean(courseNode.hasPassedConfigured()));
-			if(courseNode.hasPassedConfigured()) {
+			assessmentInfosContainer.contextPut("hasPassedField", new Boolean(assessmentConfig.hasPassedConfigured()));
+			if(assessmentConfig.hasPassedConfigured()) {
 				Boolean passed = scoreEval.getPassed();
 				assessmentInfosContainer.contextPut("passed", passed);
 				assessmentInfosContainer.contextPut("hasPassedValue", new Boolean(passed != null));
-				Float cutValue = courseNode.getCutValueConfiguration();
+				Float cutValue = assessmentConfig.getCutValueConfiguration();
 				assessmentInfosContainer.contextPut("passedCutValue", AssessmentHelper.getRoundedScore(cutValue));
 			}
 
 			// get comment
 			if(resultsVisible) {
-				if(courseNode.hasCommentConfigured()) {
+				if(assessmentConfig.hasCommentConfigured()) {
 					AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager();
 					String comment = am.getNodeComment(courseNode, getIdentity());
 					assessmentInfosContainer.contextPut("comment", comment);
 					assessmentInfosContainer.contextPut("incomment", isPanelOpen(ureq, "comment", true));
 				}
 				
-				if(courseNode.hasIndividualAsssessmentDocuments()) {
+				if(assessmentConfig.hasIndividualAsssessmentDocuments()) {
 					List<File> docs = courseNode.getIndividualAssessmentDocuments(userCourseEnv);
 					String mapperUri = registerCacheableMapper(ureq, null, new DocumentsMapper(docs));
 					assessmentInfosContainer.contextPut("docsMapperUri", mapperUri);
diff --git a/src/main/java/org/olat/course/nodes/projectbroker/ProjectBrokerAssessmentConfig.java b/src/main/java/org/olat/course/nodes/projectbroker/ProjectBrokerAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f24613d0953f8d780afa4b7c97ea9bb79206369
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/projectbroker/ProjectBrokerAssessmentConfig.java
@@ -0,0 +1,72 @@
+/**
+ * <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.projectbroker;
+
+import org.olat.course.assessment.handler.ModuleAssessmentConfig;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class ProjectBrokerAssessmentConfig extends ModuleAssessmentConfig {
+
+	public ProjectBrokerAssessmentConfig(ModuleConfiguration config) {
+		super(config);
+	}
+	
+	@Override
+	public boolean hasScoreConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasPassedConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasCommentConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return false;
+	}
+	
+	@Override
+	public boolean hasStatusConfigured() {
+		return false; // Project broker Course node has no status-field
+	}
+	
+	@Override
+	public boolean isEditableConfigured() {
+		return false;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/nodes/scorm/ScormAssessmentConfig.java b/src/main/java/org/olat/course/nodes/scorm/ScormAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a964de1171998f6fe2aeb2e280e308ed454592a
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/scorm/ScormAssessmentConfig.java
@@ -0,0 +1,108 @@
+/**
+ * <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.scorm;
+
+import org.olat.course.assessment.handler.AssessmentConfig;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class ScormAssessmentConfig implements AssessmentConfig {
+	
+	private final ModuleConfiguration config;
+
+	public ScormAssessmentConfig(ModuleConfiguration config) {
+		this.config = config;
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		boolean assessable = config.getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
+		if (assessable) {
+			String type = config.getStringValue(ScormEditController.CONFIG_ASSESSABLE_TYPE,
+					ScormEditController.CONFIG_ASSESSABLE_TYPE_SCORE);
+			return ScormEditController.CONFIG_ASSESSABLE_TYPE_SCORE.equals(type);
+		}
+		return false;
+	}
+
+	@Override
+	public Float getMaxScoreConfiguration() {
+		// According to SCORM Standard, SCORE is between 0 and 100.
+		return Float.valueOf(100);
+	}
+
+	@Override
+	public Float getMinScoreConfiguration() {
+		// According to SCORM Standard, SCORE is between 0 and 100.
+		return Float.valueOf(0);
+	}
+	
+	@Override
+	public boolean hasPassedConfigured() {
+		return config.getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
+	}
+	
+	@Override
+	public Float getCutValueConfiguration() {
+		int cutValue = config.getIntegerSafe(ScormEditController.CONFIG_CUTVALUE, 0); 
+		return Float.valueOf(cutValue);
+	}
+	
+	@Override
+	public boolean hasCompletion() {
+		return false;
+	}
+	
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return config.getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
+	}
+
+	@Override
+	public boolean hasCommentConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return false;
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean isAssessedBusinessGroups() {
+		return false;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		return config.getBooleanSafe(ScormEditController.CONFIG_ISASSESSABLE, true);
+	}
+
+}
diff --git a/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java b/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java
index 774754cdea0e3766ae464cf4fa4f0347dffe59e5..a5a469e9b583817dd44af09baed69bbf375f6057 100644
--- a/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java
+++ b/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java
@@ -52,6 +52,7 @@ import org.olat.core.util.UserSession;
 import org.olat.core.util.Util;
 import org.olat.core.util.event.GenericEventListener;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.editor.NodeEditController;
 import org.olat.course.highscore.ui.HighScoreRunController;
 import org.olat.course.nodes.CourseNode;
@@ -243,7 +244,8 @@ public class ScormRunController extends BasicController implements ScormAPICallb
 			startPage.contextPut("passed", scoreEval.getPassed());
 			boolean resultsVisible = scoreEval.getUserVisible() == null || scoreEval.getUserVisible().booleanValue();
 			startPage.contextPut("resultsVisible", resultsVisible);
-			if(resultsVisible && scormNode.hasCommentConfigured()) {
+			AssessmentConfig assessmentConfig = scormNode.getAssessmentConfig();
+			if(resultsVisible && assessmentConfig.hasCommentConfigured()) {
 				StringBuilder comment = Formatter.stripTabsAndReturns(scormNode.getUserComment(userCourseEnv));
 				startPage.contextPut("comment", StringHelper.xssScan(comment));
 			}
diff --git a/src/main/java/org/olat/course/nodes/st/STAssessmentConfig.java b/src/main/java/org/olat/course/nodes/st/STAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff152cfb79620e4e6474875023daabac9d8f698c
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/st/STAssessmentConfig.java
@@ -0,0 +1,107 @@
+/**
+ * <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.st;
+
+import org.olat.core.logging.OLATRuntimeException;
+import org.olat.core.util.StringHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
+import org.olat.course.run.scoring.ScoreCalculator;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class STAssessmentConfig implements AssessmentConfig {
+	
+	private final ScoreCalculator scoreCalculator;
+
+	public STAssessmentConfig(ScoreCalculator scoreCalculator) {
+		this.scoreCalculator = scoreCalculator;
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		if (scoreCalculator != null && StringHelper.containsNonWhitespace(scoreCalculator.getScoreExpression())) {
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public Float getMaxScoreConfiguration() {
+		throw new OLATRuntimeException(STAssessmentConfig.class, "Max score never defined for ST nodes", null);
+	}
+
+	@Override
+	public Float getMinScoreConfiguration() {
+		throw new OLATRuntimeException(STAssessmentConfig.class, "Min score never defined for ST nodes", null);
+	}
+
+	@Override
+	public boolean hasPassedConfigured() {
+		if (scoreCalculator != null && StringHelper.containsNonWhitespace(scoreCalculator.getPassedExpression())) {
+			return true;
+		}
+		return false;
+	}
+	
+	@Override
+	public Float getCutValueConfiguration() {
+		throw new OLATRuntimeException(STAssessmentConfig.class, "Cut value never defined for ST nodes", null);
+	}
+
+	@Override
+	public boolean hasCompletion() {
+		return false;
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasCommentConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return false;
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return false;
+	}
+
+	@Override
+	public boolean isAssessedBusinessGroups() {
+		return false;
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		// ST nodes never editable, data generated on the fly
+		return false;
+	}
+}
diff --git a/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java b/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java
index e76ca97d8e97cc4c2a3ac04c88343e50c6a959e9..5f7964148ed5ad1b14a5563fcd257ebaf8d0a175 100644
--- a/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java
+++ b/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java
@@ -429,7 +429,7 @@ public class STCourseNodeEditController extends ActivateableTabbableDefaultContr
 	}
 	
 	private void updateHighscoreTab() {
-		Boolean sf = stNode.hasScoreConfigured();
+		Boolean sf = stNode.getAssessmentConfig().hasScoreConfigured();
 		myTabbedPane.setEnabled(5, sf);
 	}
 	/**
diff --git a/src/main/java/org/olat/course/nodes/st/STCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/st/STCourseNodeRunController.java
index ce53e687a0139cc5087c5c6c5fb633126493d724..477ab28a22855e3f09239723bf85edd792d2aa51 100644
--- a/src/main/java/org/olat/course/nodes/st/STCourseNodeRunController.java
+++ b/src/main/java/org/olat/course/nodes/st/STCourseNodeRunController.java
@@ -46,6 +46,7 @@ import org.olat.core.logging.activity.CourseLoggingAction;
 import org.olat.core.logging.activity.StringResourceableType;
 import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.config.CourseConfig;
 import org.olat.course.highscore.ui.HighScoreRunController;
 import org.olat.course.nodes.CourseNode;
@@ -97,7 +98,8 @@ public class STCourseNodeRunController extends BasicController {
 		myContent = createVelocityContainer("run");
 		myContent.setDomReplacementWrapperRequired(false); // we provide our own DOM replacement ID
 		
-		if (se != null && (stCourseNode.hasScoreConfigured() || stCourseNode.hasPassedConfigured())) {
+		AssessmentConfig assessmentConfig = stCourseNode.getAssessmentConfig();
+		if (se != null && (assessmentConfig.hasScoreConfigured() || assessmentConfig.hasPassedConfigured())) {
 			HighScoreRunController highScoreCtr = new HighScoreRunController(ureq, wControl, userCourseEnv, stCourseNode);
 			if (highScoreCtr.isViewHighscore()) {
 				Component highScoreComponent = highScoreCtr.getInitialComponent();
@@ -172,10 +174,10 @@ public class STCourseNodeRunController extends BasicController {
 			myContent.contextPut("hasScore", Boolean.FALSE);
 			myContent.contextPut("hasPassed", Boolean.FALSE);
 		} else {
-			myContent.contextPut("hasScore", new Boolean(stCourseNode.hasScoreConfigured()));
-			myContent.contextPut("hasPassed", new Boolean(stCourseNode.hasPassedConfigured()));
+			myContent.contextPut("hasScore", new Boolean(assessmentConfig.hasScoreConfigured()));
+			myContent.contextPut("hasPassed", new Boolean(assessmentConfig.hasPassedConfigured()));
 
-			if(stCourseNode.hasScoreConfigured() || stCourseNode.hasPassedConfigured()) {
+			if(assessmentConfig.hasScoreConfigured() || assessmentConfig.hasPassedConfigured()) {
 				CourseConfig cc = userCourseEnv.getCourseEnvironment().getCourseConfig();
 				if((cc.isEfficencyStatementEnabled() || cc.isCertificateEnabled())
 						&& userCourseEnv.hasEfficiencyStatementOrCertificate(false)) {
@@ -244,6 +246,7 @@ public class STCourseNodeRunController extends BasicController {
 	/**
 	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
 	 */
+	@Override
 	protected void doDispose() {
 	// nothing to do yet
 	}
diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java
index 03afe10e10ebf89aa736721dcfbcf4e8ebaa6332..c71c422eefe1adfb5d329eecaad812793f935316 100644
--- a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java
+++ b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java
@@ -211,7 +211,7 @@ public class DropboxScoringViewController extends BasicController {
 		// insert Status Pull-Down Menu depending on user role == author
 		boolean isAuthor = ureq.getUserSession().getRoles().isAuthor();
 		boolean isTutor  = userCourseEnv.isCoach();
-		if ( ((AssessableCourseNode)node).hasStatusConfigured() && (isAuthor || isTutor)) {
+		if ( ((AssessableCourseNode)node).getAssessmentConfig().hasStatusConfigured() && (isAuthor || isTutor)) {
 			myContent.contextPut("hasStatusPullDown", Boolean.TRUE);
 			statusForm = new StatusForm(ureq, getWindowControl(), userCourseEnv.isCourseReadOnly());
 			listenTo(statusForm);
@@ -397,6 +397,7 @@ public class DropboxScoringViewController extends BasicController {
 	 * 
 	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
 	 */
+	@Override
 	protected void doDispose() {
 		//
 	}
diff --git a/src/main/java/org/olat/course/nodes/ta/TAAssessmentConfig.java b/src/main/java/org/olat/course/nodes/ta/TAAssessmentConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cdb4a8b87b8f443100a5f5734f9a34ca875f270
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/ta/TAAssessmentConfig.java
@@ -0,0 +1,82 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.course.nodes.ta;
+
+import org.olat.course.assessment.handler.ModuleAssessmentConfig;
+import org.olat.course.nodes.TACourseNode;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 19 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class TAAssessmentConfig extends ModuleAssessmentConfig {
+
+	private final boolean hasNoScoring;
+
+	public TAAssessmentConfig(ModuleConfiguration config) {
+		super(config);
+		this.hasNoScoring = !config.getBooleanSafe(TACourseNode.CONF_SCORING_ENABLED);
+	}
+
+	@Override
+	public boolean hasScoreConfigured() {
+		if (hasNoScoring) return false;
+		
+		return super.hasScoreConfigured();
+	}
+	
+	@Override
+	public boolean hasPassedConfigured() {
+		if (hasNoScoring) return false;
+		
+		return super.hasPassedConfigured();
+	}
+
+	@Override
+	public boolean hasAttemptsConfigured() {
+		return true;
+	}
+	
+	@Override
+	public boolean hasCommentConfigured() {
+		if (hasNoScoring) return false;
+		
+		return super.hasCommentConfigured();
+	}
+
+	@Override
+	public boolean hasIndividualAsssessmentDocuments() {
+		return false;
+	}
+
+	@Override
+	public boolean hasStatusConfigured() {
+		return true; // Task Course node has always a status-field
+	}
+
+	@Override
+	public boolean isEditableConfigured() {
+		return true;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/reminder/rule/PassedRuleSPI.java b/src/main/java/org/olat/course/reminder/rule/PassedRuleSPI.java
index e6017e73c7e55c1a582ecb7d33d1450281b11c7d..0995f85fb2066d10121a2a1440909a056e0fdaf9 100644
--- a/src/main/java/org/olat/course/reminder/rule/PassedRuleSPI.java
+++ b/src/main/java/org/olat/course/reminder/rule/PassedRuleSPI.java
@@ -24,12 +24,13 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.olat.core.id.Identity;
 import org.apache.logging.log4j.Logger;
+import org.olat.core.id.Identity;
 import org.olat.core.logging.Tracing;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.export.CourseEnvironmentMapper;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.STCourseNode;
@@ -99,7 +100,8 @@ public class PassedRuleSPI implements FilterRuleSPI {
 				passeds = new HashMap<>();
 				
 				STCourseNode structureNode = (STCourseNode)courseNode;
-				if(structureNode.hasPassedConfigured()) {
+				AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+				if(assessmentConfig.hasPassedConfigured()) {
 					for(Identity identity:identities) {
 						UserCourseEnvironment uce = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
 						ScoreEvaluation scoreEval = structureNode.getUserScoreEvaluation(uce);
diff --git a/src/main/java/org/olat/course/reminder/rule/ScoreRuleSPI.java b/src/main/java/org/olat/course/reminder/rule/ScoreRuleSPI.java
index c7f92432979ac7b7728d654205eee7a5a4558efc..a1b499211f0d16f67fb57be69758fc6cfb25ba31 100644
--- a/src/main/java/org/olat/course/reminder/rule/ScoreRuleSPI.java
+++ b/src/main/java/org/olat/course/reminder/rule/ScoreRuleSPI.java
@@ -24,12 +24,13 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.olat.core.id.Identity;
 import org.apache.logging.log4j.Logger;
+import org.olat.core.id.Identity;
 import org.olat.core.logging.Tracing;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.assessment.AssessmentHelper;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.export.CourseEnvironmentMapper;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.STCourseNode;
@@ -101,7 +102,8 @@ public class ScoreRuleSPI implements FilterRuleSPI {
 				scores = new HashMap<>();
 				
 				STCourseNode structureNode = (STCourseNode)courseNode;
-				if(structureNode.hasScoreConfigured()) {
+				AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+				if(assessmentConfig.hasScoreConfigured()) {
 					for(Identity identity:identities) {
 						UserCourseEnvironment uce = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course);
 						ScoreEvaluation scoreEval = structureNode.getUserScoreEvaluation(uce);
diff --git a/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java b/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java
index dc3684a3b41a5e192396971b7d5de85349fdd997..90518609fe804fb8c9deb9166bbaac809dada66f 100644
--- a/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java
+++ b/src/main/java/org/olat/course/reminder/ui/AttemptsRuleEditor.java
@@ -34,6 +34,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.QTICourseNode;
@@ -145,7 +146,8 @@ public class AttemptsRuleEditor extends RuleEditorFragment {
 	private void searchAttemptableNodes(CourseNode courseNode, List<CourseNode> nodes) {
 		if (courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
-			if (assessableCourseNode.hasAttemptsConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if (assessmentConfig.hasAttemptsConfigured()) {
 				nodes.add(courseNode);
 			}
 		} else if (courseNode instanceof QTICourseNode) {
diff --git a/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java b/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java
index 100332efaf2bd64fa25c1e12878c22ee72f8b47b..1fed9012235d0a07591a0946064c0e28be14b3eb 100644
--- a/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java
+++ b/src/main/java/org/olat/course/reminder/ui/InitialAttemptsRuleEditor.java
@@ -35,6 +35,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.reminder.rule.InitialAttemptsRuleSPI;
@@ -154,7 +155,8 @@ public class InitialAttemptsRuleEditor extends RuleEditorFragment {
 	private void searchAttemptableNodes(CourseNode courseNode, List<CourseNode> nodes) {
 		if (courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
-			if (assessableCourseNode.hasAttemptsConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if (assessmentConfig.hasAttemptsConfigured()) {
 				nodes.add(courseNode);
 			}
 		}
diff --git a/src/main/java/org/olat/course/reminder/ui/PassedRuleEditor.java b/src/main/java/org/olat/course/reminder/ui/PassedRuleEditor.java
index 5d2a5c35ab326fd24942ee29ffe76493e3f2c37d..76eb61ead559ea9db80d9253266763d7d6492f68 100644
--- a/src/main/java/org/olat/course/reminder/ui/PassedRuleEditor.java
+++ b/src/main/java/org/olat/course/reminder/ui/PassedRuleEditor.java
@@ -34,6 +34,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.reminder.rule.PassedRuleSPI;
@@ -140,7 +141,8 @@ public class PassedRuleEditor extends RuleEditorFragment {
 	private void searchPassedNodes(CourseNode courseNode, List<CourseNode> nodes) {
 		if (courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
-			if (assessableCourseNode.hasPassedConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if (assessmentConfig.hasPassedConfigured()) {
 				nodes.add(courseNode);
 			}
 		}
diff --git a/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java b/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java
index 55fd2852379ead53a3a612191e7575c9556b3cf3..d8eff9a827157567fd47360e866286d57130d0e3 100644
--- a/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java
+++ b/src/main/java/org/olat/course/reminder/ui/ScoreRuleEditor.java
@@ -143,7 +143,7 @@ public class ScoreRuleEditor extends RuleEditorFragment {
 	private void searchScoreableNodes(CourseNode courseNode, List<CourseNode> nodes) {
 		if (courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode) courseNode;
-			if (assessableCourseNode.hasScoreConfigured()) {
+			if (assessableCourseNode.getAssessmentConfig().hasScoreConfigured()) {
 				nodes.add(courseNode);
 			}
 		}
diff --git a/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java b/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java
index 9fb73638fc8c259a25b62c589ebea72e6e5a6404..48fd59d44bee149fde088003d1f716babc3bd4db 100644
--- a/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java
+++ b/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java
@@ -21,6 +21,7 @@ package org.olat.course.run.scoring;
 
 import java.util.Date;
 
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.modules.assessment.AssessmentEntry;
 import org.olat.modules.assessment.model.AssessmentEntryStatus;
@@ -122,29 +123,31 @@ public class AssessmentEvaluation extends ScoreEvaluation {
 			return AssessmentEvaluation.EMPTY_EVAL;
 		}
 		
+		AssessmentConfig assessmentConfig = node.getAssessmentConfig();
+		
 		Integer attempts = null;
-		if(node.hasAttemptsConfigured()) {
+		if(assessmentConfig.hasAttemptsConfigured()) {
 			attempts = entry.getAttempts();
 		}
 		
 		Float score = null;
-		if(node.hasScoreConfigured()) {
+		if(assessmentConfig.hasScoreConfigured()) {
 			score = entry.getScore() == null ? null : entry.getScore().floatValue();
 		}
 		
 		Boolean passed = null;
-		if(node.hasPassedConfigured()) {
+		if(assessmentConfig.hasPassedConfigured()) {
 			passed = entry.getPassed();
 		}
 		
 		String comment = null;
-		if(node.hasCommentConfigured()) {
+		if(assessmentConfig.hasCommentConfigured()) {
 			comment = entry.getComment();
 		}
 		
 		Double currentRunCompletion = null;
 		AssessmentRunStatus runStatus = null;
-		if(node.hasCompletion()) {
+		if(assessmentConfig.hasCompletion()) {
 			currentRunCompletion = entry.getCurrentRunCompletion();
 			runStatus = entry.getCurrentRunStatus();
 		}
diff --git a/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java b/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java
index e30a6d54c7b60e231d6c52f1933b4257abc47207..b7019eb00b2f2b5a1bd15f48b0e8b58181bc1a0f 100644
--- a/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java
+++ b/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java
@@ -40,6 +40,7 @@ import org.olat.core.logging.Tracing;
 import org.olat.core.util.nodes.INode;
 import org.olat.core.util.tree.TreeVisitor;
 import org.olat.core.util.tree.Visitor;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.condition.interpreter.ConditionInterpreter;
 import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.nodes.AssessableCourseNode;
@@ -200,7 +201,8 @@ public class ScoreAccounting {
 		 */
 		private AssessmentEvaluation calculateScoreEvaluation(AssessmentEntry entry, CalculatedAssessableCourseNode cNode) {
 			AssessmentEvaluation se;
-			if(cNode.hasScoreConfigured() || cNode.hasPassedConfigured()) {
+			AssessmentConfig assessmentConfig = cNode.getAssessmentConfig();
+			if(assessmentConfig.hasScoreConfigured() || assessmentConfig.hasPassedConfigured()) {
 				ScoreCalculator scoreCalculator = cNode.getScoreCalculator();
 				String scoreExpressionStr = scoreCalculator.getScoreExpression();
 				String passedExpressionStr = scoreCalculator.getPassedExpression();
@@ -216,10 +218,10 @@ public class ScoreAccounting {
 				
 				AssessmentEntryStatus assessmentStatus = AssessmentEntryStatus.inProgress;
 				ConditionInterpreter ci = userCourseEnvironment.getConditionInterpreter();
-				if (cNode.hasScoreConfigured() && scoreExpressionStr != null) {
+				if (assessmentConfig.hasScoreConfigured() && scoreExpressionStr != null) {
 					score = Float.valueOf(ci.evaluateCalculation(scoreExpressionStr));
 				}
-				if (cNode.hasPassedConfigured() && passedExpressionStr != null) {
+				if (assessmentConfig.hasPassedConfigured() && passedExpressionStr != null) {
 					boolean hasPassed = ci.evaluateCondition(passedExpressionStr);
 					if(hasPassed) {
 						passed = Boolean.TRUE;
diff --git a/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java b/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java
index 1414b8d55303b5a8405d6289394b8d6732f52c0d..4b539c18efe1b303c1ea6602f52b06aff8842369 100644
--- a/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java
+++ b/src/main/java/org/olat/ims/qti21/manager/archive/QTI21ArchiveFormat.java
@@ -33,6 +33,7 @@ import java.util.Map;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.translator.Translator;
@@ -40,7 +41,6 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.User;
 import org.olat.core.id.context.BusinessControlFactory;
 import org.olat.core.id.context.ContextEntry;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
@@ -55,6 +55,7 @@ import org.olat.core.util.openxml.workbookstyle.CellStyle;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.archiver.ExportFormat;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.AssessableCourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.fileresource.FileResourceManager;
@@ -324,11 +325,12 @@ public class QTI21ArchiveFormat {
 		// course node points and passed
 		if(courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode)courseNode;
-			if(assessableCourseNode.hasScoreConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if(assessmentConfig.hasScoreConfigured()) {
 				header1Row.addCell(col++, translator.translate("archive.table.header.node"), headerStyle);
 			}
-			if(assessableCourseNode.hasPassedConfigured()) {
-				if(assessableCourseNode.hasScoreConfigured()) {
+			if(assessmentConfig.hasPassedConfigured()) {
+				if(assessmentConfig.hasScoreConfigured()) {
 					col++;
 				} else {
 					header1Row.addCell(col++, translator.translate("archive.table.header.node"), headerStyle);
@@ -402,10 +404,11 @@ public class QTI21ArchiveFormat {
 		// course node points and passed
 		if(courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode)courseNode;
-			if(assessableCourseNode.hasScoreConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if(assessmentConfig.hasScoreConfigured()) {
 				header2Row.addCell(col++, translator.translate("archive.table.header.node.points"), headerStyle);
 			}
-			if(assessableCourseNode.hasPassedConfigured()) {
+			if(assessmentConfig.hasPassedConfigured()) {
 				header2Row.addCell(col++, translator.translate("archive.table.header.node.passed"), headerStyle);
 			}
 		}
@@ -535,14 +538,15 @@ public class QTI21ArchiveFormat {
 		// course node points and passed
 		if(courseNode instanceof AssessableCourseNode) {
 			AssessableCourseNode assessableCourseNode = (AssessableCourseNode)courseNode;
-			if(assessableCourseNode.hasScoreConfigured()) {
+			AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+			if(assessmentConfig.hasScoreConfigured()) {
 				if(entry.getScore() != null) {
 					dataRow.addCell(col++, entry.getScore(), null);
 				} else {
 					col++;
 				}
 			}
-			if(assessableCourseNode.hasPassedConfigured()) {
+			if(assessmentConfig.hasPassedConfigured()) {
 				if(entry.getPassed() != null) {
 					dataRow.addCell(col++, entry.getPassed().toString(), null);
 				} else {
diff --git a/src/main/java/org/olat/ims/qti21/ui/statistics/QTI21AssessmentTestStatisticsController.java b/src/main/java/org/olat/ims/qti21/ui/statistics/QTI21AssessmentTestStatisticsController.java
index b4767e793843d184c5fa8553eb3f9804146cef75..e0ed96478ec8bf9ebbddd7bc2491076878624b47 100644
--- a/src/main/java/org/olat/ims/qti21/ui/statistics/QTI21AssessmentTestStatisticsController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/statistics/QTI21AssessmentTestStatisticsController.java
@@ -154,7 +154,7 @@ public class QTI21AssessmentTestStatisticsController extends BasicController imp
 	private Float getMaxScoreSetting(QTICourseNode testNode) {
 		Float maxScoreSetting = null;
 		if(QTIType.qtiworks.equals(type)) {
-			maxScoreSetting = testNode instanceof IQTESTCourseNode ? ((IQTESTCourseNode)testNode).getMaxScoreConfiguration() : null;
+			maxScoreSetting = testNode instanceof IQTESTCourseNode ? ((IQTESTCourseNode)testNode).getAssessmentConfig().getMaxScoreConfiguration() : null;
 		}
 		return maxScoreSetting;
 	}
@@ -162,7 +162,7 @@ public class QTI21AssessmentTestStatisticsController extends BasicController imp
 	private Float getCutValueSetting(QTICourseNode testNode) {
 		Float cutValueSetting = null;
 		if(QTIType.qtiworks.equals(type)) {
-			cutValueSetting = testNode instanceof IQTESTCourseNode ? ((IQTESTCourseNode)testNode).getCutValueConfiguration() : null;
+			cutValueSetting = testNode instanceof IQTESTCourseNode ? ((IQTESTCourseNode)testNode).getAssessmentConfig().getCutValueConfiguration() : null;
 		}
 		return cutValueSetting;
 	}
diff --git a/src/main/java/org/olat/modules/portfolio/BinderConfiguration.java b/src/main/java/org/olat/modules/portfolio/BinderConfiguration.java
index 5467884efdcc6fe0b8c260e04b5a4743c31a935e..20cdcdb728bc45411a581c2c3aa6f8136e8cff11 100644
--- a/src/main/java/org/olat/modules/portfolio/BinderConfiguration.java
+++ b/src/main/java/org/olat/modules/portfolio/BinderConfiguration.java
@@ -24,6 +24,7 @@ import org.olat.core.logging.Tracing;
 import org.olat.course.CorruptedCourseException;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.PortfolioCourseNode;
 import org.olat.repository.RepositoryEntry;
@@ -142,13 +143,13 @@ public class BinderConfiguration {
 				displayname = course.getCourseTitle();
 				CourseNode courseNode = course.getRunStructure().getNode(binder.getSubIdent());
 				if(courseNode instanceof PortfolioCourseNode) {
-					PortfolioCourseNode pfNode = (PortfolioCourseNode)courseNode;
-					withScore = pfNode.hasScoreConfigured();
+					AssessmentConfig assessmentConfig = courseNode.getAssessmentConfig();
+					withScore = assessmentConfig.hasScoreConfigured();
 					if(withScore) {
-						maxScore = pfNode.getMaxScoreConfiguration();
-						minScore = pfNode.getMinScoreConfiguration();
+						maxScore = assessmentConfig.getMaxScoreConfiguration();
+						minScore = assessmentConfig.getMinScoreConfiguration();
 					}
-					withPassed = pfNode.hasPassedConfigured();
+					withPassed = assessmentConfig.hasPassedConfigured();
 					assessable = withPassed || withScore;
 				} else {
 					withPassed = true;
diff --git a/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java b/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java
index 19c4c73f7f78badc6e582b3c9653340e2cef7422..0720b705974b438e342a7dc76a1e64b1d77dac89 100644
--- a/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java
+++ b/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java
@@ -36,6 +36,7 @@ import java.util.Properties;
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.modules.bc.FolderConfig;
@@ -44,11 +45,11 @@ import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.media.StringMediaResource;
 import org.olat.core.id.Identity;
 import org.olat.core.id.IdentityEnvironment;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.handler.AssessmentConfig;
 import org.olat.course.assessment.manager.AssessmentNotificationsHandler;
 import org.olat.course.nodes.ScormCourseNode;
 import org.olat.course.nodes.scorm.ScormEditController;
@@ -113,10 +114,11 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
 	private void currentScore() {
 		if(isAssessable) {
 			checkForLms();
-			if(scormNode.hasScoreConfigured()) {
+			AssessmentConfig assessmentConfig = scormNode.getAssessmentConfig();
+			if(assessmentConfig.hasScoreConfigured()) {
 				currentScore = scormNode.getUserScoreEvaluation(userCourseEnv).getScore();
 			}
-			if(scormNode.hasPassedConfigured()) {
+			if(assessmentConfig.hasPassedConfigured()) {
 				currentPassed = scormNode.getUserScoreEvaluation(userCourseEnv).getPassed();
 			}
 		}
@@ -251,7 +253,8 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
 			score += ascore;
 		}
 		
-		float cutval = scormNode.getCutValueConfiguration().floatValue();
+		AssessmentConfig assessmentConfig = scormNode.getAssessmentConfig();
+		float cutval = assessmentConfig.getCutValueConfiguration().floatValue();
 		boolean passed = (score >= cutval);
 		// if advanceScore option is set update the score only if it is higher
 		// <OLATEE-27>
@@ -300,6 +303,7 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable {
 		}
 	}
 
+	@Override
 	public MediaResource handle(String relPath, HttpServletRequest request) {
 		check();
 		
diff --git a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java
index 4159b6e391bf0066bcf85c70c3043d7395aeae22..b2929d1f810fc17490e47f432792cdf0630c3ef5 100644
--- a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java
+++ b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java
@@ -1086,7 +1086,7 @@ public class ReminderRuleEngineTest extends OlatTestCase {
 			}
 		}
 		Assert.assertNotNull(testNode);
-		Assert.assertTrue(testNode.hasScoreConfigured());
+		Assert.assertTrue(testNode.getAssessmentConfig().hasScoreConfigured());
 		
 		IdentityEnvironment ienv = new IdentityEnvironment(); 
 		ienv.setIdentity(student);