diff --git a/src/main/java/de/thm/arsnova/controller/SessionController.java b/src/main/java/de/thm/arsnova/controller/SessionController.java
index a1b25aa68c6ef4c6a5911962a04c58db8701fd7c..f76d377d31c73c90b972d34eea637833870718c2 100644
--- a/src/main/java/de/thm/arsnova/controller/SessionController.java
+++ b/src/main/java/de/thm/arsnova/controller/SessionController.java
@@ -234,17 +234,19 @@ public class SessionController extends AbstractController {
 	@RequestMapping(value = "/{sessionkey}/learningprogress", method = RequestMethod.GET)
 	public final int learningProgress(
 			@PathVariable final String sessionkey,
+			@RequestParam(value = "type", defaultValue = "questions") final String progressType,
 			final HttpServletResponse response
 			) {
-		return sessionService.getLearningProgress(sessionkey);
+		return sessionService.getLearningProgress(sessionkey, progressType);
 	}
 
 	@RequestMapping(value = "/{sessionkey}/mylearningprogress", method = RequestMethod.GET)
 	public final JSONObject myLearningProgress(
 			@PathVariable final String sessionkey,
+			@RequestParam(value = "type", defaultValue = "questions") final String progressType,
 			final HttpServletResponse response
 			) {
-		final SimpleEntry<Integer, Integer> result = sessionService.getMyLearningProgress(sessionkey);
+		final SimpleEntry<Integer, Integer> result = sessionService.getMyLearningProgress(sessionkey, progressType);
 		final JSONObject json = new JSONObject();
 		json.put("myprogress", result.getKey());
 		json.put("courseprogress", result.getValue());
diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 44ae691a84bb115fdef2455cc54394fa3233095b..cdb87b61d141b95d6dfae563e6278f876d587d41 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -18,8 +18,6 @@
 package de.thm.arsnova.dao;
 
 import java.io.IOException;
-import java.util.AbstractMap;
-import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -53,6 +51,7 @@ import com.fourspaces.couchdb.View;
 import com.fourspaces.couchdb.ViewResults;
 
 import de.thm.arsnova.connector.model.Course;
+import de.thm.arsnova.domain.CourseScore;
 import de.thm.arsnova.entities.Answer;
 import de.thm.arsnova.entities.DbUser;
 import de.thm.arsnova.entities.InterposedQuestion;
@@ -403,6 +402,7 @@ public class CouchDBDao implements IDatabaseDao {
 		sessionDocument.put("courseType", session.getCourseType());
 		sessionDocument.put("courseId", session.getCourseId());
 		sessionDocument.put("creationTime", session.getCreationTime());
+		sessionDocument.put("learningProgressType", session.getLearningProgressType());
 		sessionDocument.put("ppAuthorName", session.getPpAuthorName());
 		sessionDocument.put("ppAuthorMail", session.getPpAuthorMail());
 		sessionDocument.put("ppUniversity", session.getPpUniversity());
@@ -1291,6 +1291,7 @@ public class CouchDBDao implements IDatabaseDao {
 			s.put("name", session.getName());
 			s.put("shortName", session.getShortName());
 			s.put("active", session.isActive());
+			s.put("learningProgressType", session.getLearningProgressType());
 			database.saveDocument(s);
 			session.set_rev(s.getRev());
 
@@ -1634,64 +1635,39 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int getLearningProgress(final Session session) {
-		// Note: we have to use this many views because our CouchDB version does not support
-		// advanced features like summing over lists. Thus, we have to do it all by ourselves...
-		final NovaView maximumValueView = new NovaView("learning_progress_maximum_value/max");
-		final NovaView answerSumView = new NovaView("learning_progress_user_values/sum");
-		final NovaView answerDocumentCountView = new NovaView("learning_progress_course_answers/count");
-		maximumValueView.setKey(session.get_id());
+	public CourseScore getLearningProgress(final Session session) {
+		final NovaView maximumValueView = new NovaView("learning_progress/maximum_value_of_question");
+		final NovaView answerSumView = new NovaView("learning_progress/question_value_achieved_for_user");
+		maximumValueView.setStartKeyArray(session.get_id());
+		maximumValueView.setEndKeyArray(session.get_id(), "{}");
 		answerSumView.setStartKeyArray(session.get_id());
 		answerSumView.setEndKeyArray(session.get_id(), "{}");
-		answerDocumentCountView.setStartKeyArray(session.get_id());
-		answerDocumentCountView.setEndKeyArray(session.get_id(), "{}");
-		answerDocumentCountView.setGroup(true);
 
 		final List<Document> maximumValueResult = getDatabase().view(maximumValueView).getResults();
 		final List<Document> answerSumResult = getDatabase().view(answerSumView).getResults();
-		final List<Document> answerDocumentCountResult = getDatabase().view(answerDocumentCountView).getResults();
 
-		if (maximumValueResult.isEmpty() || answerSumResult.isEmpty() || answerDocumentCountResult.isEmpty()) {
-			return 0;
-		}
-
-		final double courseMaximumValue = maximumValueResult.get(0).getInt("value");
-		final double userTotalValue = answerSumResult.get(0).getInt("value");
-		final double numUsers = answerDocumentCountResult.size();
-		if (courseMaximumValue == 0 || numUsers == 0) {
-			return 0;
-		}
-		final double courseAverageValue = userTotalValue / numUsers;
-		final double courseProgress = courseAverageValue / courseMaximumValue;
-		return (int) Math.min(100, Math.round(courseProgress * 100));
-	}
-
-	@Override
-	public SimpleEntry<Integer, Integer> getMyLearningProgress(final Session session, final User user) {
-		final int courseProgress = getLearningProgress(session);
-
-		final NovaView maximumValueView = new NovaView("learning_progress_maximum_value/max");
-		final NovaView answerSumView = new NovaView("learning_progress_user_values/sum");
-		maximumValueView.setKey(session.get_id());
-		answerSumView.setKey(session.get_id(), user.getUsername());
-
-		final List<Document> maximumValueResult = getDatabase().view(maximumValueView).getResults();
-		final List<Document> answerSumResult = getDatabase().view(answerSumView).getResults();
+		CourseScore courseScore = new CourseScore();
 
+		// no results found
 		if (maximumValueResult.isEmpty() || answerSumResult.isEmpty()) {
-			return new AbstractMap.SimpleEntry<Integer, Integer>(0, courseProgress);
+			return courseScore;
 		}
 
-		final double courseMaximumValue = maximumValueResult.get(0).getInt("value");
-		final double userTotalValue = answerSumResult.get(0).getInt("value");
-
-		if (courseMaximumValue == 0) {
-			return new AbstractMap.SimpleEntry<Integer, Integer>(0, courseProgress);
+		// collect mapping (questionId -> max value)
+		for (Document d : maximumValueResult) {
+			String questionId = d.getJSONArray("key").getString(1);
+			int questionScore = d.getInt("value");
+			courseScore.add(questionId, questionScore);
 		}
-		final double myProgress = userTotalValue / courseMaximumValue;
-		final int myLearningProgress = (int) Math.min(100, Math.round(myProgress * 100));
-
-		return new AbstractMap.SimpleEntry<Integer, Integer>(myLearningProgress, courseProgress);
+		// collect mapping (questionId -> (user -> value))
+		for (Document d : answerSumResult) {
+			String username = d.getJSONArray("key").getString(1);
+			JSONObject value = d.getJSONObject("value");
+			String questionId = value.getString("questionId");
+			int userscore = value.getInt("score");
+			courseScore.add(questionId, username, userscore);
+		}
+		return courseScore;
 	}
 
 	@Override
diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
index 6f534be9401c6180e7c508e3f2db3c0f809e7975..d688abbebe96b06212afe87a79157ccd996444ce 100644
--- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
+++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
@@ -17,10 +17,10 @@
  */
 package de.thm.arsnova.dao;
 
-import java.util.AbstractMap.SimpleEntry;
 import java.util.List;
 
 import de.thm.arsnova.connector.model.Course;
+import de.thm.arsnova.domain.CourseScore;
 import de.thm.arsnova.entities.Answer;
 import de.thm.arsnova.entities.DbUser;
 import de.thm.arsnova.entities.InterposedQuestion;
@@ -171,9 +171,7 @@ public interface IDatabaseDao {
 
 	boolean deleteUser(DbUser dbUser);
 
-	int getLearningProgress(Session session);
-
-	SimpleEntry<Integer, Integer> getMyLearningProgress(Session session, User user);
+	CourseScore getLearningProgress(Session session);
 
 	List<SessionInfo> getMySessionsInfo(User user);
 
diff --git a/src/main/java/de/thm/arsnova/domain/CourseScore.java b/src/main/java/de/thm/arsnova/domain/CourseScore.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa3c9d92ec565bb578032076a7412e3d84759e3d
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/CourseScore.java
@@ -0,0 +1,92 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.domain;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import de.thm.arsnova.entities.User;
+
+public class CourseScore implements Iterable<QuestionScore> {
+
+	private final Map<String, QuestionScore> scores = new HashMap<String, QuestionScore>();
+
+	public void add(String questionId, int questionScore) {
+		scores.put(questionId, new QuestionScore(questionId, questionScore));
+	}
+
+	/**
+	 * @pre questionId has been added before.
+	 * @param questionId
+	 * @param username
+	 * @param userscore
+	 */
+	public void add(String questionId, String username, int userscore) {
+		if (!scores.containsKey(questionId)) {
+			// Precondition failed, ignore this element.
+			// Most likely this is a question that has no learning progress value.
+			return;
+		}
+		QuestionScore questionScore = scores.get(questionId);
+		questionScore.add(username, userscore);
+	}
+
+	public int getMaximumScore() {
+		int score = 0;
+		for (QuestionScore questionScore : this) {
+			score += questionScore.getMaximum();
+		}
+		return score;
+	}
+
+	public int getTotalUserScore() {
+		int score = 0;
+		for (QuestionScore questionScore : this) {
+			score += questionScore.getTotalUserScore();
+		}
+		return score;
+	}
+
+	public double getTotalUserScore(User user) {
+		int score = 0;
+		for (QuestionScore questionScore : this) {
+			score += questionScore.getTotalUserScore(user);
+		}
+		return score;
+	}
+
+	public int getTotalUserCount() {
+		Set<String> users = new HashSet<String>();
+		for (QuestionScore questionScore : this) {
+			questionScore.collectUsers(users);
+		}
+		return users.size();
+	}
+
+	public int getQuestionCount() {
+		return scores.size();
+	}
+
+	@Override
+	public Iterator<QuestionScore> iterator() {
+		return this.scores.values().iterator();
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/domain/LearningProgress.java b/src/main/java/de/thm/arsnova/domain/LearningProgress.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8ccfbfedc80275bfaedfff91cf00cfbab1aa76b
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/LearningProgress.java
@@ -0,0 +1,30 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.domain;
+
+import java.util.AbstractMap.SimpleEntry;
+
+import de.thm.arsnova.entities.Session;
+import de.thm.arsnova.entities.User;
+
+public interface LearningProgress {
+
+	public int getCourseProgress(Session session);
+
+	public SimpleEntry<Integer,Integer> getMyProgress(Session session, User user);
+}
diff --git a/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java b/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f819d410e0b95b018ce3cb38f1f16713d8b3907
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/LearningProgressFactory.java
@@ -0,0 +1,22 @@
+package de.thm.arsnova.domain;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import de.thm.arsnova.dao.IDatabaseDao;
+
+@Component
+public class LearningProgressFactory {
+
+	@Autowired
+	private IDatabaseDao databaseDao;
+
+	public LearningProgress createFromType(String progressType) {
+		if (progressType.equals("questions")) {
+			return new QuestionBasedLearningProgress(databaseDao);
+		} else {
+			return new PointBasedLearningProgress(databaseDao);
+		}
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/domain/PointBasedLearningProgress.java b/src/main/java/de/thm/arsnova/domain/PointBasedLearningProgress.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7168bc0c05dee16423a4e4d7a847aae24db3eb2
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/PointBasedLearningProgress.java
@@ -0,0 +1,70 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.domain;
+
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleEntry;
+
+import de.thm.arsnova.dao.IDatabaseDao;
+import de.thm.arsnova.entities.Session;
+import de.thm.arsnova.entities.User;
+
+public class PointBasedLearningProgress implements LearningProgress {
+
+	private IDatabaseDao databaseDao;
+
+	public PointBasedLearningProgress(IDatabaseDao dao) {
+		this.databaseDao = dao;
+	}
+
+	@Override
+	public int getCourseProgress(Session session) {
+		CourseScore courseScore = databaseDao.getLearningProgress(session);
+		return calculateCourseScore(courseScore);
+	}
+
+	private int calculateCourseScore(CourseScore courseScore) {
+		final double courseMaximumValue = courseScore.getMaximumScore();
+		final double userTotalValue = courseScore.getTotalUserScore();
+		final double numUsers = courseScore.getTotalUserCount();
+		if (courseMaximumValue == 0 || numUsers == 0) {
+			return 0;
+		}
+		final double courseAverageValue = userTotalValue / numUsers;
+		final double courseProgress = courseAverageValue / courseMaximumValue;
+		return (int)Math.min(100, Math.round(courseProgress * 100));
+	}
+
+	@Override
+	public SimpleEntry<Integer, Integer> getMyProgress(Session session, User user) {
+		CourseScore courseScore = databaseDao.getLearningProgress(session);
+		int courseProgress = calculateCourseScore(courseScore);
+
+		final double courseMaximumValue = courseScore.getMaximumScore();
+		final double userTotalValue = courseScore.getTotalUserScore(user);
+
+		if (courseMaximumValue == 0) {
+			return new AbstractMap.SimpleEntry<Integer, Integer>(0, courseProgress);
+		}
+		final double myProgress = userTotalValue / courseMaximumValue;
+		final int myLearningProgress = (int)Math.min(100, Math.round(myProgress*100));
+
+		return new AbstractMap.SimpleEntry<Integer, Integer>(myLearningProgress, courseProgress);
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/domain/QuestionBasedLearningProgress.java b/src/main/java/de/thm/arsnova/domain/QuestionBasedLearningProgress.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1ea2d45103cf5e3eee2e8ea8e82368a37ab8f3c
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/QuestionBasedLearningProgress.java
@@ -0,0 +1,101 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.domain;
+
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleEntry;
+
+import de.thm.arsnova.dao.IDatabaseDao;
+import de.thm.arsnova.entities.Session;
+import de.thm.arsnova.entities.User;
+
+public class QuestionBasedLearningProgress implements LearningProgress {
+
+	private IDatabaseDao databaseDao;
+
+	public QuestionBasedLearningProgress(IDatabaseDao dao) {
+		this.databaseDao = dao;
+	}
+
+	@Override
+	public int getCourseProgress(Session session) {
+		CourseScore courseScore = databaseDao.getLearningProgress(session);
+		return calculateCourseProgress(courseScore);
+	}
+
+	private int calculateCourseProgress(CourseScore courseScore) {
+		int numQuestionsCorrect = numQuestionsCorrectForCourse(courseScore);
+		final double correctQuestionsOnAverage = (double)numQuestionsCorrect / (double)(courseScore.getQuestionCount());
+		// calculate percent, cap results to 100
+		return (int) Math.min(100, Math.round(correctQuestionsOnAverage*100));
+	}
+
+	private int numQuestionsCorrectForCourse(CourseScore courseScore) {
+		// a question is seen as "correct" if and only if all participants have answered it correctly
+		int numQuestionsCorrect = 0;
+		for (QuestionScore questionScore : courseScore) {
+			int requiredScore = questionScore.getMaximum();
+			if (!questionScore.hasScores()) {
+				continue;
+			}
+			boolean allCorrect = true;
+			for (UserScore userScore : questionScore) {
+				if (!userScore.hasScore(requiredScore)) {
+					allCorrect = false;
+					break;
+				}
+			}
+			if (allCorrect) {
+				numQuestionsCorrect++;
+			}
+		}
+		return numQuestionsCorrect;
+	}
+
+	@Override
+	public SimpleEntry<Integer, Integer> getMyProgress(Session session, User user) {
+		CourseScore courseScore = databaseDao.getLearningProgress(session);
+
+		int courseProgress = calculateCourseProgress(courseScore);
+
+		int numQuestionsCorrect = numQuestionsCorrectForUser(user, courseScore);
+		final double myLearningProgress = numQuestionsCorrect / (double)(courseScore.getQuestionCount());
+		// calculate percent, cap results to 100
+		final int percentage = (int) Math.min(100, Math.round(myLearningProgress*100));
+		return new AbstractMap.SimpleEntry<Integer, Integer>(percentage, courseProgress);
+	}
+
+	private int numQuestionsCorrectForUser(User user, CourseScore courseScore) {
+		// compare user's values to the maximum number for each question to determine the answers' correctness
+		// mapping (questionId -> 1 if correct, 0 if incorrect)
+		int numQuestionsCorrect = 0;
+		for (QuestionScore questionScore : courseScore) {
+			int requiredScore = questionScore.getMaximum();
+			for (UserScore userScore : questionScore) {
+				if (!userScore.isUser(user)) {
+					continue;
+				}
+				if (userScore.hasScore(requiredScore)) {
+					numQuestionsCorrect++;
+				}
+			}
+		}
+		return numQuestionsCorrect;
+	}
+
+}
diff --git a/src/main/java/de/thm/arsnova/domain/QuestionScore.java b/src/main/java/de/thm/arsnova/domain/QuestionScore.java
new file mode 100644
index 0000000000000000000000000000000000000000..457c84edd876201fd9834efe90f1bc2d411fbbb5
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/QuestionScore.java
@@ -0,0 +1,84 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.domain;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import de.thm.arsnova.entities.User;
+
+public class QuestionScore implements Iterable<UserScore> {
+
+	private String questionId;
+
+	private int maximumScore;
+
+	private List<UserScore> userScores = new ArrayList<UserScore>();
+
+	public QuestionScore(String questionId, int maximumScore) {
+		this.questionId = questionId;
+		this.maximumScore = maximumScore;
+	}
+
+	public int getMaximum() {
+		return this.maximumScore;
+	}
+
+	@Override
+	public Iterator<UserScore> iterator() {
+		return this.userScores.iterator();
+	}
+
+	public boolean hasScores() {
+		return this.userScores.size() > 0;
+	}
+
+	public void add(String username, int userscore) {
+		userScores.add(new UserScore(username, userscore));
+	}
+
+	public int getTotalUserScore() {
+		int totalScore = 0;
+		for (UserScore score : userScores) {
+			totalScore += score.getScore();
+		}
+		return totalScore;
+	}
+
+	public int getTotalUserScore(User user) {
+		int totalScore = 0;
+		for (UserScore score : userScores) {
+			if (score.isUser(user)) {
+				totalScore += score.getScore();
+			}
+		}
+		return totalScore;
+	}
+
+	public int getUserCount() {
+		return userScores.size();
+	}
+
+	public void collectUsers(Set<String> users) {
+		for (UserScore score : userScores) {
+			users.add(score.getUsername());
+		}
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/domain/UserScore.java b/src/main/java/de/thm/arsnova/domain/UserScore.java
new file mode 100644
index 0000000000000000000000000000000000000000..282fd06e7e73692997fee753e597b91e0c84cfde
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/UserScore.java
@@ -0,0 +1,48 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.domain;
+
+import de.thm.arsnova.entities.User;
+
+public class UserScore {
+
+	private String username;
+
+	private int score;
+
+	public UserScore(String username, int score) {
+		this.username = username;
+		this.score = score;
+	}
+
+	public boolean hasScore(int score) {
+		return this.score == score;
+	}
+
+	public int getScore() {
+		return score;
+	}
+
+	public boolean isUser(User user) {
+		return user.getUsername().equals(username);
+	}
+
+	public String getUsername() {
+		return username;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/domain/package-info.java b/src/main/java/de/thm/arsnova/domain/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee2d2f1de66118173509e1ba7b8f66e6acf2343f
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/domain/package-info.java
@@ -0,0 +1 @@
+package de.thm.arsnova.domain;
\ No newline at end of file
diff --git a/src/main/java/de/thm/arsnova/entities/Session.java b/src/main/java/de/thm/arsnova/entities/Session.java
index 78e7dbd386229bac08d0d68fb7d38f95109b1e19..467bf26ba80da0e6012b58b8032d9d884776da98 100644
--- a/src/main/java/de/thm/arsnova/entities/Session.java
+++ b/src/main/java/de/thm/arsnova/entities/Session.java
@@ -37,6 +37,7 @@ public class Session implements Serializable {
 	private String courseId;
 	private List<String> _conflicts;
 	private long creationTime;
+	private String learningProgressType = "questions";
 
 	private String ppAuthorName;
 	private String ppAuthorMail;
@@ -68,6 +69,8 @@ public class Session implements Serializable {
 		copy.lastOwnerActivity = original.lastOwnerActivity;
 		copy.courseType = original.courseType;
 		copy.courseId = original.courseId;
+		copy.creationTime = original.creationTime;
+		copy.learningProgressType = original.learningProgressType;
 		copy._id = original._id;
 		copy._rev = original._rev;
 		return copy;
@@ -186,6 +189,14 @@ public class Session implements Serializable {
 		this.creationTime = creationTime;
 	}
 
+	public String getLearningProgressType() {
+		return learningProgressType;
+	}
+
+	public void setLearningProgressType(String learningProgressType) {
+		this.learningProgressType = learningProgressType;
+	}
+
 	public String getPpAuthorName() {
 		return ppAuthorName;
 	}
diff --git a/src/main/java/de/thm/arsnova/entities/transport/LearningProgressType.java b/src/main/java/de/thm/arsnova/entities/transport/LearningProgressType.java
new file mode 100644
index 0000000000000000000000000000000000000000..4293c34b1258757b37b70878c8429845e98aa913
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/entities/transport/LearningProgressType.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of ARSnova Backend.
+ * Copyright (C) 2012-2015 The ARSnova Team
+ *
+ * ARSnova Backend is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARSnova Backend is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package de.thm.arsnova.entities.transport;
+
+public class LearningProgressType {
+
+	private String sessionKeyword;
+
+	private String learningProgressType;
+
+	public String getSessionKeyword() {
+		return sessionKeyword;
+	}
+
+	public void setSessionKeyword(String sessionKeyword) {
+		this.sessionKeyword = sessionKeyword;
+	}
+
+	public String getLearningProgressType() {
+		return learningProgressType;
+	}
+
+	public void setLearningProgressType(String learningProgressType) {
+		this.learningProgressType = learningProgressType;
+	}
+}
diff --git a/src/main/java/de/thm/arsnova/services/ISessionService.java b/src/main/java/de/thm/arsnova/services/ISessionService.java
index a65413aad83d0860a34d0eac85ec45e6901ee199..9104ddfbe6b94ec4defb9e82809cf57d3991a5f9 100644
--- a/src/main/java/de/thm/arsnova/services/ISessionService.java
+++ b/src/main/java/de/thm/arsnova/services/ISessionService.java
@@ -24,11 +24,14 @@ import java.util.UUID;
 import de.thm.arsnova.connector.model.Course;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.SessionInfo;
+import de.thm.arsnova.entities.User;
 import de.thm.arsnova.entities.transport.ImportExportSession;
 
 public interface ISessionService {
 	Session getSession(String keyword);
 
+	Session getSessionInternal(String keyword, User user);
+
 	Session saveSession(Session session);
 
 	boolean sessionKeyAvailable(String keyword);
@@ -49,11 +52,13 @@ public interface ISessionService {
 
 	Session updateSession(String sessionkey, Session session);
 
+	Session updateSessionInternal(Session session, User user);
+
 	void deleteSession(String sessionkey);
 
-	int getLearningProgress(String sessionkey);
+	int getLearningProgress(String sessionkey, String progressType);
 
-	SimpleEntry<Integer, Integer> getMyLearningProgress(String sessionkey);
+	SimpleEntry<Integer, Integer> getMyLearningProgress(String sessionkey, String progressType);
 
 	List<SessionInfo> getMySessionsInfo();
 
diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java
index d3d0267a663fb5c921e5755f06ff2dd29b165c10..9d490dad1513d956a1cbb40a9099eaf47c117887 100644
--- a/src/main/java/de/thm/arsnova/services/SessionService.java
+++ b/src/main/java/de/thm/arsnova/services/SessionService.java
@@ -34,6 +34,8 @@ import de.thm.arsnova.ImageUtils;
 import de.thm.arsnova.connector.client.ConnectorClient;
 import de.thm.arsnova.connector.model.Course;
 import de.thm.arsnova.dao.IDatabaseDao;
+import de.thm.arsnova.domain.LearningProgress;
+import de.thm.arsnova.domain.LearningProgressFactory;
 import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.SessionInfo;
@@ -93,6 +95,9 @@ public class SessionService implements ISessionService {
 	@Autowired
 	private ARSnovaSocketIOServer socketIoServer;
 
+	@Autowired
+	private LearningProgressFactory learningProgressFactory;
+
 	@Autowired(required = false)
 	private ConnectorClient connectorClient;
 
@@ -138,6 +143,15 @@ public class SessionService implements ISessionService {
 	@PreAuthorize("isAuthenticated()")
 	public final Session getSession(final String keyword) {
 		final User user = userService.getCurrentUser();
+		return this.getSessionInternal(keyword, user);
+	}
+
+	/*
+	 * The "internal" suffix means it is called by internal services that have no authentication!
+	 * TODO: Find a better way of doing this...
+	 */
+	@Override
+	public final Session getSessionInternal(final String keyword, final User user) {
 		final Session session = databaseDao.getSessionFromKeyword(keyword);
 		if (session == null) {
 			throw new NotFoundException();
@@ -274,6 +288,18 @@ public class SessionService implements ISessionService {
 		return databaseDao.updateSession(session);
 	}
 
+	/*
+	 * The "internal" suffix means it is called by internal services that have no authentication!
+	 * TODO: Find a better way of doing this...
+	 */
+	@Override
+	public Session updateSessionInternal(final Session session, final User user) {
+		if (session.isCreator(user)) {
+			return databaseDao.updateSession(session);
+		}
+		return null;
+	}
+
 	@Override
 	@PreAuthorize("isAuthenticated() and hasPermission(#sessionkey, 'session', 'owner')")
 	public void deleteSession(final String sessionkey) {
@@ -286,17 +312,19 @@ public class SessionService implements ISessionService {
 
 	@Override
 	@PreAuthorize("isAuthenticated()")
-	public int getLearningProgress(final String sessionkey) {
+	public int getLearningProgress(final String sessionkey, final String progressType) {
 		final Session session = databaseDao.getSession(sessionkey);
-		return databaseDao.getLearningProgress(session);
+		LearningProgress learningProgress = learningProgressFactory.createFromType(progressType);
+		return learningProgress.getCourseProgress(session);
 	}
 
 	@Override
 	@PreAuthorize("isAuthenticated()")
-	public SimpleEntry<Integer, Integer> getMyLearningProgress(final String sessionkey) {
+	public SimpleEntry<Integer, Integer> getMyLearningProgress(final String sessionkey, final String progressType) {
 		final Session session = databaseDao.getSession(sessionkey);
 		final User user = userService.getCurrentUser();
-		return databaseDao.getMyLearningProgress(session, user);
+		LearningProgress learningProgress = learningProgressFactory.createFromType(progressType);
+		return learningProgress.getMyProgress(session, user);
 	}
 
 	@Override
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
index 2cb748b7c183b3ae23f68633ca7991005dd09d64..8cf4e7451b6dc1730f0e41abd02db033b440b509 100644
--- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
@@ -48,6 +48,7 @@ import com.corundumstudio.socketio.protocol.PacketType;
 
 import de.thm.arsnova.entities.InterposedQuestion;
 import de.thm.arsnova.entities.User;
+import de.thm.arsnova.entities.transport.LearningProgressType;
 import de.thm.arsnova.events.DeleteAnswerEvent;
 import de.thm.arsnova.events.NewAnswerEvent;
 import de.thm.arsnova.events.NewInterposedQuestionEvent;
@@ -188,6 +189,22 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No
 			}
 		});
 
+		server.addEventListener(
+				"setLearningProgressType",
+				LearningProgressType.class,
+				new DataListener<LearningProgressType>() {
+			@Override
+			public void onData(SocketIOClient client, LearningProgressType progressType, AckRequest ack) {
+				final User user = userService.getUser2SocketId(client.getSessionId());
+				final de.thm.arsnova.entities.Session session = sessionService.getSessionInternal(progressType.getSessionKeyword(), user);
+				if (session.isCreator(user)) {
+					session.setLearningProgressType(progressType.getLearningProgressType());
+					sessionService.updateSessionInternal(session, user);
+					broadcastInSession(session.getKeyword(), "learningProgressType", progressType.getLearningProgressType());
+				}
+			}
+		});
+
 		server.addConnectListener(new ConnectListener() {
 			@Override
 			public void onConnect(final SocketIOClient client) { }
@@ -316,11 +333,13 @@ public class ARSnovaSocketIOServer implements ApplicationListener<NovaEvent>, No
 	 * @param client
 	 */
 	public void reportSessionDataToClient(final String sessionKey, final User user, final SocketIOClient client) {
+		final de.thm.arsnova.entities.Session session = sessionService.getSessionInternal(sessionKey, user);
 		client.sendEvent("unansweredLecturerQuestions", questionService.getUnAnsweredLectureQuestionIds(sessionKey, user));
 		client.sendEvent("unansweredPreparationQuestions", questionService.getUnAnsweredPreparationQuestionIds(sessionKey, user));
 		client.sendEvent("countLectureQuestionAnswers", questionService.countLectureQuestionAnswersInternal(sessionKey));
 		client.sendEvent("countPreparationQuestionAnswers", questionService.countPreparationQuestionAnswersInternal(sessionKey));
 		client.sendEvent("activeUserCountData", sessionService.activeUsers(sessionKey));
+		client.sendEvent("learningProgressType", session.getLearningProgressType());
 		final de.thm.arsnova.entities.Feedback fb = feedbackService.getFeedback(sessionKey);
 		client.sendEvent("feedbackData", fb.getValues());
 		try {
diff --git a/src/main/webapp/WEB-INF/spring/spring-main.xml b/src/main/webapp/WEB-INF/spring/spring-main.xml
index b9bedd607523757fe09fd2554f21851a8eaa0b7f..e5141f7570cf970dfb379f5dc75f9ab957286c4e 100644
--- a/src/main/webapp/WEB-INF/spring/spring-main.xml
+++ b/src/main/webapp/WEB-INF/spring/spring-main.xml
@@ -23,7 +23,7 @@
 		<property name="fileEncoding" value="UTF-8" />
 	</bean>
 
-	<context:component-scan base-package="de.thm.arsnova.dao,de.thm.arsnova.events,de.thm.arsnova.security,de.thm.arsnova.services,de.thm.arsnova.config" />
+	<context:component-scan base-package="de.thm.arsnova.dao,de.thm.arsnova.events,de.thm.arsnova.security,de.thm.arsnova.services,de.thm.arsnova.config,de.thm.arsnova.domain" />
 
 	<context:annotation-config />
 
diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
index d9ce9195a221128da561b562e8f36b999438b656..a0e26baa9cfab05611458c9b4d82eb68deb2fed9 100644
--- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
+++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
@@ -18,13 +18,13 @@
  */
 package de.thm.arsnova.dao;
 
-import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import de.thm.arsnova.connector.model.Course;
+import de.thm.arsnova.domain.CourseScore;
 import de.thm.arsnova.entities.Answer;
 import de.thm.arsnova.entities.DbUser;
 import de.thm.arsnova.entities.Feedback;
@@ -510,13 +510,7 @@ public class StubDatabaseDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int getLearningProgress(Session session) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public SimpleEntry<Integer, Integer> getMyLearningProgress(Session session, User user) {
+	public CourseScore getLearningProgress(Session session) {
 		// TODO Auto-generated method stub
 		return null;
 	}