diff --git a/README.md b/README.md
index 87be8ef895ca6ea300339e02cf23da113873cf49..9646c934fbbae587ac3ddae0cc74befa3357a465 100644
--- a/README.md
+++ b/README.md
@@ -4,18 +4,67 @@ ARSnova is a modern approach to Audience Response Systems (ARS). It is released
 
 ![ARSnova](src/site/resources/showcase.png)
 
-ARSnova consists of two projects: the mobile client and the server. This repository contains the server code. You will find the client at thm-projects/arsnova-st2-js. However, you do not need to download both respositories in order to get started.
+ARSnova consists of two projects: the mobile client and the server. This repository contains the server code. You will find the client at thm-projects/arsnova-mobile. However, you do not need to download both repositories in order to get started.
 
 ## Getting Started
 
-This is the main repository. Almost all dependencies (including the mobile client) are managed for you by Maven.  The mobile client is served via `index.html`, and optionally via `developer.html`. 
+This is the main repository. Almost all dependencies (including the mobile client) are managed for you by Maven.
 
-## Configuration
+### Download
 
-You will need to do some configuration work upfront.
+If you have no intention in contributing, you might want to consider downloading one of our pre-built WAR archives. You will find them in our [Maven repository](https://maven.mni.thm.de/content/repositories/snapshots/de/thm/arsnova/arsnova-war/2.0.0-SNAPSHOT/), but please do note that we are not officially offering these archives.
 
- * Add a new directory "arsnova" in `/etc`, and create a copy of arsnova.properties.example named arsnova.properties in this directory.
- * Change settings to match your environment
+### Building
+
+ARSnova consists of two main projects: arsnova-war (this repository) and arsnova-mobile. By building arsnova-war, you will automatically download the mobile client. If you do not plan to work on the client, you won't need to build it separately.
+
+Because all dependencies are handled by Maven, a complete build is done with:
+
+	mvn install
+
+### Development
+
+You need three things to get started developing ARSnova:
+
+1. the configuration file,
+2. a CouchDB database including several view documents,
+3. and a development server.
+
+We will cover all three in the following sections.
+
+#### Configuration
+
+You will need to do some configuration work upfront: add a new directory "arsnova" in `/etc`, and create a copy of [arsnova.properties.example](src/main/webapp/arsnova.properties.example) named `arsnova.properties` in this directory. Then change the settings to match your environment, e.g. you might want to change the URLs.
+
+Also, don't forget to change all properties starting with `couchdb`, if you do not want to use our defaults. The properties are used in the next section.
+
+*A note to Windows users*: our settings are based on Linux and Mac environments. We do not officially support Windows, so you have to do some extra steps. The property file's path is hard coded in [spring-main.xml](src/main/webapp/WEB-INF/spring/spring-main.xml) and in the "Setup Tool" (see next section). You want to change the paths to make them match your environment. 
+
+#### Database
+
+We provide a Python script that will set up all database essentials. This "Setup Tool" is located at [thm-projects/setuptool](https://github.com/thm-projects/setuptool). Make sure you have configured your database credentials inside the ARSnova configuration file (see previous section): you will need to have the entries `couchdb.username` and `couchdb.password`.
+
+To set up the database, run:
+	
+	python tool.py
+
+This will create the database along with all required view documents. Note that this script requires Python 2 and will not run with Python 3.
+
+#### Developer Mode
+
+The easiest way to deploy ARSnova is via Jetty:
+
+	mvn jetty:run -Dmobile.path=
+	
+This will work out of the box. ARSnova will be located at <http://localhost:8080/>. 
+
+If you're wondering what that `-Dmobile.path=` thing is doing, this is a special override property for Jetty. By default, this property points to a local version of ARSnova mobile located at `../arsnova-mobile` &mdash; relative to the location of this project. If you happen to have downloaded ARSnova mobile to this location, you may skip the override, and just use:
+	
+	mvn jetty:run
+
+## Production Use
+
+If you intend to use ARSnova in productive environments, you will have to do some additional configuration work.
 
 ### Server
 
@@ -42,14 +91,6 @@ To enable the required Apache Webserver modules simply type:
 
 The configuration is ready for development usage. Finally, you should (re)start all services. ARSnova is now listening on HTTP port 80.
 
-### Database
-
-We provide a script that will set up all database essentials. This "Setup Tool" is located at <https://github.com/thm-projects/setuptool>. Make sure you have configured your database credentials inside the ARSnova configuration file: you will need to have the entries `couchdb.username` and `couchdb.password`.
-
-## Production Use
-
-If you intend to use ARSnova in productive environments, you will have to do some additional configuration work.
-
 ### Session Persistence
 
 Look for your Tomcat configuration directory and change the file "context.xml" to match this example:
diff --git a/pom.xml b/pom.xml
index 5a5ab7c37148104f4061ef4d509ed5a6919ce737..704e851c19935b64fc3d79cdfa0ef934a81e24a5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,6 +11,7 @@
 		<org.springframework.security-version>3.1.4.RELEASE</org.springframework.security-version>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.url>https://scm.thm.de/arsnova</project.url>
+		<mobile.path>../arsnova-mobile/src/main/webapp/build/production/ARSnova</mobile.path>
 	</properties>
 
 	<developers>
@@ -364,17 +365,17 @@
 					<scanIntervalSeconds>1</scanIntervalSeconds>
 					<webApp> 
 						<contextPath>/</contextPath>
-						<!--<baseResource implementation="org.eclipse.jetty.util.resource.ResourceCollection">
-							<resourcesAsCSV>src/main/webapp,../arsnova-mobile/src/main/webapp</resourcesAsCSV> 
+						<baseResource implementation="org.eclipse.jetty.util.resource.ResourceCollection">
+							<resourcesAsCSV>src/main/webapp,${mobile.path}</resourcesAsCSV>
 						</baseResource>
-						<overrideDescriptor>src/main/webapp/WEB-INF/web-dev.xml</overrideDescriptor>-->
+						<overrideDescriptor>src/main/webapp/WEB-INF/web-dev.xml</overrideDescriptor>
 					</webApp>
 				</configuration>
 			</plugin>
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-site-plugin</artifactId>
-				<version>3.1</version>
+				<version>3.3</version>
 				<configuration>
 					<locales>en</locales>
 				</configuration>
diff --git a/src/main/java/de/thm/arsnova/FeedbackStorage.java b/src/main/java/de/thm/arsnova/FeedbackStorage.java
index 7f62d24c32e3f87709eca27b7332603b0edb4b94..dcdd11b845d1301489dee7d6f08e4e47baeaddf1 100644
--- a/src/main/java/de/thm/arsnova/FeedbackStorage.java
+++ b/src/main/java/de/thm/arsnova/FeedbackStorage.java
@@ -1,7 +1,6 @@
 package de.thm.arsnova;
 
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -41,7 +40,7 @@ public class FeedbackStorage {
 	private IDatabaseDao dao;
 	
 	public FeedbackStorage(IDatabaseDao newDao) {
-		this.data = new ConcurrentHashMap<String, Map<String,FeedbackStorageObject>>();
+		this.data = new ConcurrentHashMap<String, Map<String, FeedbackStorageObject>>();
 		this.dao = newDao;
 	}
 
@@ -104,8 +103,6 @@ public class FeedbackStorage {
 			data.put(keyword, new ConcurrentHashMap<String, FeedbackStorageObject>());
 		}
 		
-		System.out.println(user.getUsername());
-		
 		data.get(keyword).put(user.getUsername(), new FeedbackStorageObject(value, user));
 		return true;
 	}
diff --git a/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java b/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java
index 56f1158cd966511b8efb2b74a0b0cb3163ef079d..bfe0dad441bf1bc57c68f54585aafba56e701feb 100644
--- a/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java
+++ b/src/main/java/de/thm/arsnova/aop/UserSessionAspect.java
@@ -1,7 +1,5 @@
 package de.thm.arsnova.aop;
 
-import java.util.UUID;
-
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.annotation.AfterReturning;
 import org.aspectj.lang.annotation.Aspect;
diff --git a/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java b/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java
index d390d7a5f05a172e78c944e1b9c63acc792f5537..5b606d54e098552f0e566e5bedc5de74d62c6aaa 100644
--- a/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java
+++ b/src/main/java/de/thm/arsnova/controller/AudienceQuestionController.java
@@ -117,4 +117,5 @@ public class AudienceQuestionController extends AbstractController {
 	) {
 		questionService.deleteInterposedQuestion(questionId);
 	}
+
 }
diff --git a/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java b/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java
index fec00c97a4bb5dbe430e1b7a7b96179d81c1fdfd..a26dc791ca87297e75f9efee72864026337f4e84 100644
--- a/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java
+++ b/src/main/java/de/thm/arsnova/controller/LecturerQuestionController.java
@@ -99,6 +99,20 @@ public class LecturerQuestionController extends AbstractController {
 		}
 		this.questionService.update(question);
 	}
+	
+	@RequestMapping(value = "/publish", method = RequestMethod.POST)
+	@ResponseBody
+	public final void publishAllQuestions(
+			@RequestParam final String sessionkey,
+			@RequestParam(required = false) final Boolean publish,
+			final HttpServletResponse response
+	) {
+		boolean p = true;
+		if (publish != null) {
+			p = publish;
+		}
+		this.questionService.publishAll(sessionkey, p);
+	}
 
 	@RequestMapping(value = "/{questionId}/publishstatistics", method = RequestMethod.POST)
 	@ResponseBody
@@ -128,19 +142,27 @@ public class LecturerQuestionController extends AbstractController {
 		this.questionService.update(question);
 	}
 
-	@RequestMapping(
-			value = { "/" },
-			method = RequestMethod.GET
-	)
+	@RequestMapping(value = "/", method = RequestMethod.GET)
 	@ResponseBody
 	public final List<Question> getSkillQuestions(
 			@RequestParam final String sessionkey,
+			@RequestParam(value = "lecturequestionsonly", defaultValue = "false") final boolean lectureQuestionsOnly,
+			@RequestParam(value = "flashcardsonly", defaultValue = "false") final boolean flashcardsOnly,
+			@RequestParam(value = "preparationquestionsonly", defaultValue = "false") final boolean preparationQuestionsOnly,
 			final HttpServletResponse response
 	) {
-		List<Question> questions = questionService.getSkillQuestions(sessionkey);
+		List<Question> questions;
+		if (lectureQuestionsOnly) {
+			questions = questionService.getLectureQuestions(sessionkey);
+		} else if (flashcardsOnly) {
+			questions = questionService.getFlashcards(sessionkey);
+		} else if (preparationQuestionsOnly) {
+			questions = questionService.getPreparationQuestions(sessionkey);
+		} else {
+			questions = questionService.getSkillQuestions(sessionkey);
+		}
 		if (questions == null || questions.isEmpty()) {
 			response.setStatus(HttpStatus.NO_CONTENT.value());
-
 			return null;
 		}
 		return questions;
@@ -148,16 +170,43 @@ public class LecturerQuestionController extends AbstractController {
 
 	@RequestMapping(value = { "/" }, method = RequestMethod.DELETE)
 	@ResponseBody
-	public final void deleteSkillQuestions(@RequestParam final String sessionkey, final HttpServletResponse response) {
-		this.questionService.deleteAllQuestions(sessionkey);
+	public final void deleteSkillQuestions(
+			@RequestParam final String sessionkey,
+			@RequestParam(value = "lecturequestionsonly", defaultValue = "false") final boolean lectureQuestionsOnly,
+			@RequestParam(value = "flashcardsonly", defaultValue = "false") final boolean flashcardsOnly,
+			@RequestParam(value = "preparationquestionsonly", defaultValue = "false") final boolean preparationQuestionsOnly,
+			final HttpServletResponse response
+	) {
+		if (lectureQuestionsOnly) {
+			this.questionService.deleteLectureQuestions(sessionkey);
+		} else if (flashcardsOnly) {
+			this.questionService.deleteFlashcards(sessionkey);
+		} else if (preparationQuestionsOnly) {
+			this.questionService.deletePreparationQuestions(sessionkey);
+		} else {
+			this.questionService.deleteAllQuestions(sessionkey);
+		}
 	}
 
 	@RequestMapping(value = "/count", method = RequestMethod.GET)
 	@ResponseBody
-	public final int getSkillQuestionCount(@RequestParam final String sessionkey, final HttpServletResponse response) {
+	public final int getSkillQuestionCount(
+			@RequestParam final String sessionkey,
+			@RequestParam(value = "lecturequestionsonly", defaultValue = "false") final boolean lectureQuestionsOnly,
+			@RequestParam(value = "flashcardsonly", defaultValue = "false") final boolean flashcardsOnly,
+			@RequestParam(value = "preparationquestionsonly", defaultValue = "false") final boolean preparationQuestionsOnly,
+			final HttpServletResponse response) {
 		response.addHeader("X-Deprecated-API", "1");
 
-		return questionService.getSkillQuestionCount(sessionkey);
+		if (lectureQuestionsOnly) {
+			return questionService.getLectureQuestionCount(sessionkey);
+		} else if (flashcardsOnly) {
+			return questionService.getFlashcardCount(sessionkey);
+		} else if (preparationQuestionsOnly) {
+			return questionService.getPreparationQuestionCount(sessionkey);
+		} else {
+			return questionService.getSkillQuestionCount(sessionkey);
+		}
 	}
 
 	@RequestMapping(value = "/{questionId}", method = RequestMethod.DELETE)
@@ -173,9 +222,18 @@ public class LecturerQuestionController extends AbstractController {
 	@ResponseBody
 	public final List<String> getUnAnsweredSkillQuestionIds(
 			@RequestParam final String sessionkey,
+			@RequestParam(value = "lecturequestionsonly", defaultValue = "false") final boolean lectureQuestionsOnly,
+			@RequestParam(value = "preparationquestionsonly", defaultValue = "false") final boolean preparationQuestionsOnly,
 			final HttpServletResponse response
 	) {
-		List<String> answers = questionService.getUnAnsweredQuestionIds(sessionkey);
+		List<String> answers;
+		if (lectureQuestionsOnly) {
+			answers = questionService.getUnAnsweredLectureQuestionIds(sessionkey);
+		} else if (preparationQuestionsOnly) {
+			answers = questionService.getUnAnsweredPreparationQuestionIds(sessionkey);
+		} else {
+			answers = questionService.getUnAnsweredQuestionIds(sessionkey);
+		}
 		if (answers == null || answers.isEmpty()) {
 			throw new NoContentException();
 		}
@@ -297,6 +355,15 @@ public class LecturerQuestionController extends AbstractController {
 		questionService.deleteAnswers(questionId);
 	}
 
+	@RequestMapping(value = "/answers", method = RequestMethod.DELETE)
+	@ResponseBody
+	public final void deleteAllQuestionsAnswers(
+			@RequestParam final String sessionkey,
+			final HttpServletResponse response
+	) {
+		questionService.deleteAllQuestionsAnswers(sessionkey);
+	}
+
 	/**
 	 *
 	 * @param sessionKey
@@ -345,11 +412,19 @@ public class LecturerQuestionController extends AbstractController {
 	@ResponseBody
 	public final int getTotalAnswerCount(
 			@RequestParam final String sessionkey,
+			@RequestParam(value = "lecturequestionsonly", defaultValue = "false") final boolean lectureQuestionsOnly,
+			@RequestParam(value = "preparationquestionsonly", defaultValue = "false") final boolean preparationQuestionsOnly,
 			final HttpServletResponse response
 	) {
 		response.addHeader("X-Deprecated-API", "1");
 
-		return questionService.getTotalAnswerCount(sessionkey);
+		if (lectureQuestionsOnly) {
+			return questionService.countLectureQuestionAnswers(sessionkey);
+		} else if (preparationQuestionsOnly) {
+			return questionService.countPreparationQuestionAnswers(sessionkey);
+		} else {
+			return questionService.getTotalAnswerCount(sessionkey);
+		}
 	}
 
 }
diff --git a/src/main/java/de/thm/arsnova/controller/LegacyController.java b/src/main/java/de/thm/arsnova/controller/LegacyController.java
index 8f2c5b7a0774467e35830a32f96d2f870e9faeee..83c049daddd8b5df8e8e246a291148a0c066fcab 100644
--- a/src/main/java/de/thm/arsnova/controller/LegacyController.java
+++ b/src/main/java/de/thm/arsnova/controller/LegacyController.java
@@ -22,16 +22,23 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import de.thm.arsnova.services.IQuestionService;
 
 @Controller
 public class LegacyController extends AbstractController {
 
 	public static final Logger LOGGER = LoggerFactory.getLogger(LegacyController.class);
 
+	@Autowired
+	private IQuestionService questionService;
+
 	/* specific routes */
 
 	@RequestMapping(value = "/session/mysessions", method = RequestMethod.GET)
@@ -115,6 +122,15 @@ public class LegacyController extends AbstractController {
 		return String.format("forward:/audiencequestion/?sessionkey=%s", sessionKey);
 	}
 
+	@RequestMapping(value = "/session/{sessionKey}/interposed", method = RequestMethod.DELETE)
+	@ResponseBody
+	public final void deleteAllInterposedQuestions(
+			@PathVariable final String sessionKey,
+			final HttpServletResponse response
+	) {
+		questionService.deleteAllInterposedQuestions(sessionKey);
+	}
+
 	@RequestMapping(value = "/session/{sessionKey}/interposedcount", method = RequestMethod.GET)
 	public final String redirectQuestionByAudienceCount(
 			@PathVariable final String sessionKey,
diff --git a/src/main/java/de/thm/arsnova/controller/SessionController.java b/src/main/java/de/thm/arsnova/controller/SessionController.java
index ecdb8b5f77a42980993451b6b5c001153d521bbb..525bd65ddea5469aed9cca1da4301d66c3749d3a 100644
--- a/src/main/java/de/thm/arsnova/controller/SessionController.java
+++ b/src/main/java/de/thm/arsnova/controller/SessionController.java
@@ -127,6 +127,15 @@ public class SessionController extends AbstractController {
 		return newSession;
 	}
 
+	@RequestMapping(value = "/{sessionkey}", method = RequestMethod.PUT)
+	@ResponseBody
+	public final Session updateSession(
+			@PathVariable final String sessionkey,
+			@RequestBody final Session session
+	) {
+		return sessionService.updateSession(sessionkey, session);
+	}
+
 	@RequestMapping(value = "/", method = RequestMethod.GET)
 	@ResponseBody
 	public final List<Session> getSessions(
diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 34aff2eff911121fc0c60b21b98807d34ea80c42..fa3b627f64a68ff157a0513bc2ac99514a3e2855 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -143,75 +143,23 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public final List<Question> getSkillQuestions(final String sessionKeyword) {
-		Session session = this.getSessionFromKeyword(sessionKeyword);
-		if (session == null) {
-			throw new NotFoundException();
-		}
-
-		User user = this.userService.getCurrentUser();
-		NovaView view = null;
-
-		try {
-			String viewName;
-			if (session.getCreator().equals(user.getUsername())) {
-				viewName = "skill_question/by_session_sorted_by_subject_and_text";
+	public final List<Question> getSkillQuestions(User user, Session session) {
+		String viewName;
+		if (session.getCreator().equals(user.getUsername())) {
+			viewName = "skill_question/by_session_sorted_by_subject_and_text";
+		} else {
+			if (user.getType().equals(User.THM)) {
+				viewName = "skill_question/by_session_for_thm_full";
 			} else {
-				if (user.getType().equals(User.THM)) {
-					viewName = "skill_question/by_session_for_thm_full";
-				} else {
-					viewName = "skill_question/by_session_for_all_full";
-				}
-			}
-			view = new NovaView(viewName);
-			view.setStartKeyArray(session.get_id());
-			view.setEndKeyArray(session.get_id(), "{}");
-
-			ViewResults questions = this.getDatabase().view(view);
-			if (questions == null || questions.isEmpty()) {
-				return null;
-			}
-			List<Question> result = new ArrayList<Question>();
-
-			MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
-			Morpher dynaMorpher = new BeanMorpher(PossibleAnswer.class, morpherRegistry);
-			morpherRegistry.registerMorpher(dynaMorpher);
-			for (Document document : questions.getResults()) {
-				Question question = (Question) JSONObject.toBean(
-						document.getJSONObject().getJSONObject("value"),
-						Question.class
-				);
-				Collection<PossibleAnswer> answers = JSONArray.toCollection(
-						document.getJSONObject().getJSONObject("value")
-							.getJSONArray("possibleAnswers"),
-						PossibleAnswer.class
-				);
-				question.setPossibleAnswers(new ArrayList<PossibleAnswer>(answers));
-				question.setSessionKeyword(this.getSessionKeyword(question.getSessionId()));
-				if (!"freetext".equals(question.getQuestionType()) && 0 == question.getPiRound()) {
-					/* needed for legacy questions whose piRound property has not been set */
-					question.setPiRound(1);
-				}
-				result.add(question);
+				viewName = "skill_question/by_session_for_all_full";
 			}
-
-			return result;
-		} catch (IOException e) {
-			return null;
 		}
+		return getQuestions(new NovaView(viewName), session);
 	}
 
 	@Override
 	public final int getSkillQuestionCount(final Session session) {
-		NovaView view = new NovaView("skill_question/count_by_session");
-		view.setKey(session.get_id());
-		ViewResults results = this.getDatabase().view(view);
-
-		if (results.getJSONArray("rows").optJSONObject(0) == null) {
-			return 0;
-		}
-
-		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
+		return getQuestionCount(new NovaView("skill_question/count_by_session"), session);
 	}
 
 	@Override
@@ -311,9 +259,23 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public final Question saveQuestion(final Session session, final Question question) {
+		Document q = toQuestionDocument(session, question);
+		try {
+			database.saveDocument(q);
+			question.set_id(q.getId());
+			question.set_rev(q.getRev());
+			return question;
+		} catch (IOException e) {
+			LOGGER.error("Could not save question {}", question);
+		}
+		return null;
+	}
+
+	private Document toQuestionDocument(final Session session, final Question question) {
 		Document q = new Document();
 		q.put("type", "skill_question");
 		q.put("questionType", question.getQuestionType());
+		q.put("questionVariant", question.getQuestionVariant());
 		q.put("sessionId", session.get_id());
 		q.put("subject", question.getSubject());
 		q.put("text", question.getText());
@@ -326,15 +288,7 @@ public class CouchDBDao implements IDatabaseDao {
 		q.put("showStatistic", question.isShowStatistic());
 		q.put("showAnswer", question.isShowAnswer());
 		q.put("abstention", question.isAbstention());
-		try {
-			database.saveDocument(q);
-			question.set_id(q.getId());
-			question.set_rev(q.getRev());
-			return question;
-		} catch (IOException e) {
-			LOGGER.error("Could not save question {}", question);
-		}
-		return null;
+		return q;
 	}
 
 	@Override
@@ -482,18 +436,8 @@ public class CouchDBDao implements IDatabaseDao {
 		} else {
 			view = new NovaView("skill_question/by_session_only_id_for_all");
 		}
-
 		view.setKey(session.get_id());
-		ViewResults results = this.getDatabase().view(view);
-		if (results.getResults().size() == 0) {
-			return new ArrayList<String>();
-		}
-
-		List<String> ids = new ArrayList<String>();
-		for (Document d : results.getResults()) {
-			ids.add(d.getId());
-		}
-		return ids;
+		return collectQuestionIds(view);
 	}
 
 	@Override
@@ -509,6 +453,10 @@ public class CouchDBDao implements IDatabaseDao {
 	@Override
 	public final void deleteAllQuestionsWithAnswers(Session session) {
 		NovaView view = new NovaView("skill_question/by_session");
+		deleteAllQuestionDocumentsWithAnswers(session, view);
+	}
+
+	private void deleteAllQuestionDocumentsWithAnswers(Session session, NovaView view) {
 		view.setStartKeyArray(session.get_id());
 		view.setEndKey(session.get_id(), "{}");
 		ViewResults results = this.getDatabase().view(view);
@@ -544,21 +492,7 @@ public class CouchDBDao implements IDatabaseDao {
 	public final List<String> getUnAnsweredQuestionIds(final Session session, final User user) {
 		NovaView view = new NovaView("answer/by_user");
 		view.setKey(user.getUsername(), session.get_id());
-		ViewResults anseweredQuestions = this.getDatabase().view(view);
-
-		List<String> answered = new ArrayList<String>();
-		for (Document d : anseweredQuestions.getResults()) {
-			answered.add(d.getString("value"));
-		}
-
-		List<String> questions = this.getQuestionIds(session, user);
-		List<String> unanswered = new ArrayList<String>();
-		for (String questionId : questions) {
-			if (!answered.contains(questionId)) {
-				unanswered.add(questionId);
-			}
-		}
-		return unanswered;
+		return collectUnansweredQuestionIds(session, user, this.getQuestionIds(session, user), view);
 	}
 
 	@Override
@@ -626,10 +560,11 @@ public class CouchDBDao implements IDatabaseDao {
 	}
 
 	@Override
-	public final int getAnswerCount(final String questionId) {
-		NovaView view = new NovaView("skill_question/count_answers_by_question");
-		view.setKey(questionId);
+	public final int getAnswerCount(final Question question, final int piRound) {
+		NovaView view = new NovaView("skill_question/count_total_answers_by_question_and_piround");
 		view.setGroup(true);
+		view.setStartKey(question.get_id(), String.valueOf(piRound));
+		view.setEndKey(question.get_id(), String.valueOf(piRound), "{}");
 		ViewResults results = this.getDatabase().view(view);
 		if (results.getResults().size() == 0) {
 			return 0;
@@ -653,19 +588,6 @@ public class CouchDBDao implements IDatabaseDao {
 		return 0;
 	}
 
-	@Override
-	public final int countActiveUsers(Session session, long since) {
-		if (session == null) throw new NotFoundException();
-		NovaView view = new NovaView("logged_in/count");
-		view.setStartKey(session.get_id(), String.valueOf(since));
-		view.setEndKey(session.get_id(), "{}");
-		ViewResults results = this.getDatabase().view(view);
-		if (isEmptyResults(results)) {
-			return 0;
-		}
-		return results.getJSONArray("rows").optJSONObject(0).getInt("value");
-	}
-
 	private boolean isEmptyResults(ViewResults results) {
 		return results == null || results.getResults().isEmpty() || results.getJSONArray("rows").size() == 0;
 	}
@@ -990,6 +912,7 @@ public class CouchDBDao implements IDatabaseDao {
 			a.put("sessionId", answer.getSessionId());
 			a.put("questionId", answer.getQuestionId());
 			a.put("answerSubject", answer.getAnswerSubject());
+			a.put("questionVariant", answer.getQuestionVariant());
 			a.put("answerText", answer.getAnswerText());
 			a.put("timestamp", answer.getTimestamp());
 			a.put("user", user.getUsername());
@@ -1100,8 +1023,7 @@ public class CouchDBDao implements IDatabaseDao {
 			sb.append("]");
 			try {
 				this.setKeys(URLEncoder.encode(sb.toString(), "UTF-8"));
-			}
-			catch (UnsupportedEncodingException e) {
+			} catch (UnsupportedEncodingException e) {
 				LOGGER.error("Error while encoding course ID keys", e);
 			}
 		}
@@ -1138,6 +1060,24 @@ public class CouchDBDao implements IDatabaseDao {
 		return null;
 	}
 
+	@Override
+	public Session updateSession(Session session) {
+		try {
+			Document s = this.database.getDocument(session.get_id());
+			s.put("name", session.getName());
+			s.put("shortName", session.getShortName());
+			s.put("active", session.isActive());
+			this.database.saveDocument(s);
+			session.set_rev(s.getRev());
+
+			return session;
+		} catch (IOException e) {
+			LOGGER.error("Could not lock session {}", session);
+		}
+
+		return null;
+	}
+
 	@Override
 	public void deleteSession(Session session) {
 		try {
@@ -1146,4 +1086,256 @@ public class CouchDBDao implements IDatabaseDao {
 			LOGGER.error("Could not delete session {}", session);
 		}
 	}
+
+	@Override
+	public List<Question> getLectureQuestions(User user, Session session) {
+		String viewName;
+		if (session.isCreator(user)) {
+			viewName = "skill_question/lecture_question_by_session";
+		} else {
+			if (user.getType().equals(User.THM)) {
+				viewName = "skill_question/lecture_question_by_session_for_thm";
+			} else {
+				viewName = "skill_question/lecture_question_by_session_for_all";
+			}
+		}
+		return getQuestions(new NovaView(viewName), session);
+	}
+
+	@Override
+	public List<Question> getFlashcards(User user, Session session) {
+		String viewName;
+		if (session.isCreator(user)) {
+			viewName = "skill_question/flashcard_by_session";
+		} else {
+			if (user.getType().equals(User.THM)) {
+				viewName = "skill_question/flashcard_by_session_for_thm";
+			} else {
+				viewName = "skill_question/flashcard_by_session_for_all";
+			}
+		}
+		return getQuestions(new NovaView(viewName), session);
+	}
+
+	@Override
+	public List<Question> getPreparationQuestions(User user, Session session) {
+		String viewName;
+		if (session.isCreator(user)) {
+			viewName = "skill_question/preparation_question_by_session";
+		} else {
+			if (user.getType().equals(User.THM)) {
+				viewName = "skill_question/preparation_question_by_session_for_thm";
+			} else {
+				viewName = "skill_question/preparation_question_by_session_for_all";
+			}
+		}
+		return getQuestions(new NovaView(viewName), session);
+		
+	}
+	
+	private List<Question> getQuestions(NovaView view, Session session) {
+		view.setStartKeyArray(session.get_id());
+		view.setEndKeyArray(session.get_id(), "{}");
+		ViewResults questions = this.getDatabase().view(view);
+		if (questions == null || questions.isEmpty()) {
+			return null;
+		}
+		List<Question> result = new ArrayList<Question>();
+
+		MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
+		Morpher dynaMorpher = new BeanMorpher(PossibleAnswer.class, morpherRegistry);
+		morpherRegistry.registerMorpher(dynaMorpher);
+		for (Document document : questions.getResults()) {
+			Question question = (Question) JSONObject.toBean(
+					document.getJSONObject().getJSONObject("value"),
+					Question.class
+			);
+			@SuppressWarnings("unchecked")
+			Collection<PossibleAnswer> answers = JSONArray.toCollection(
+					document.getJSONObject().getJSONObject("value").getJSONArray("possibleAnswers"),
+					PossibleAnswer.class
+			);
+			question.setPossibleAnswers(new ArrayList<PossibleAnswer>(answers));
+			question.setSessionKeyword(session.getKeyword());
+			if (!"freetext".equals(question.getQuestionType()) && 0 == question.getPiRound()) {
+				/* needed for legacy questions whose piRound property has not been set */
+				question.setPiRound(1);
+			}
+			result.add(question);
+		}
+		return result;
+	}
+
+	@Override
+	public int getLectureQuestionCount(Session session) {
+		return getQuestionCount(new NovaView("skill_question/lecture_question_count_by_session"), session);
+	}
+
+	@Override
+	public int getFlashcardCount(Session session) {
+		return getQuestionCount(new NovaView("skill_question/flashcard_count_by_session"), session);
+	}
+
+	@Override
+	public int getPreparationQuestionCount(Session session) {
+		return getQuestionCount(new NovaView("skill_question/preparation_question_count_by_session"), session);
+	}
+	
+	private int getQuestionCount(NovaView view, Session session) {
+		view.setKey(session.get_id());
+		ViewResults results = this.getDatabase().view(view);
+		if (results.getJSONArray("rows").optJSONObject(0) == null) {
+			return 0;
+		}
+		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
+	}
+
+	@Override
+	public int countLectureQuestionAnswers(Session session) {
+		return countQuestionVariantAnswers(session, "lecture");
+	}
+
+	@Override
+	public int countPreparationQuestionAnswers(Session session) {
+		return countQuestionVariantAnswers(session, "preparation");
+	}
+	
+	private int countQuestionVariantAnswers(Session session, String variant) {
+		NovaView view = new NovaView("skill_question/count_answers_by_session_and_question_variant");
+		view.setKey(session.get_id(), variant);
+		ViewResults results = this.getDatabase().view(view);
+		if (results.getResults().size() == 0) {
+			return 0;
+		}
+		return results.getJSONArray("rows").optJSONObject(0).optInt("value");
+	}
+
+	@Override
+	public void deleteAllLectureQuestionsWithAnswers(Session session) {
+		NovaView view = new NovaView("skill_question/lecture_question_by_session");
+		deleteAllQuestionDocumentsWithAnswers(session, view);
+	}
+
+	@Override
+	public void deleteAllFlashcardsWithAnswers(Session session) {
+		NovaView view = new NovaView("skill_question/flashcard_by_session");
+		deleteAllQuestionDocumentsWithAnswers(session, view);
+	}
+
+	@Override
+	public void deleteAllPreparationQuestionsWithAnswers(Session session) {
+		NovaView view = new NovaView("skill_question/preparation_question_by_session");
+		deleteAllQuestionDocumentsWithAnswers(session, view);
+	}
+
+	@Override
+	public List<String> getUnAnsweredLectureQuestionIds(Session session, User user) {
+		NovaView view = new NovaView("answer/variant_by_user");
+		view.setKey(user.getUsername(), session.get_id(), "lecture");
+		return collectUnansweredQuestionIds(session, user, this.getLectureQuestionIds(session, user), view);
+	}
+
+	private List<String> getLectureQuestionIds(Session session, User user) {
+		NovaView view;
+		if (user.getType().equals("thm")) {
+			view = new NovaView("skill_question/lecture_question_by_session_for_thm");
+		} else {
+			view = new NovaView("skill_question/lecture_question_by_session_for_all");
+		}
+		view.setStartKeyArray(session.get_id());
+		view.setEndKeyArray(session.get_id(), "{}");
+		return collectQuestionIds(view);
+	}
+
+	@Override
+	public List<String> getUnAnsweredPreparationQuestionIds(Session session, User user) {
+		NovaView view = new NovaView("answer/variant_by_user");
+		view.setKey(user.getUsername(), session.get_id(), "preparation");
+		return collectUnansweredQuestionIds(session, user, this.getPreparationQuestionIds(session, user), view);
+	}
+
+	private List<String> getPreparationQuestionIds(Session session, User user) {
+		NovaView view;
+		if (user.getType().equals("thm")) {
+			view = new NovaView("skill_question/preparation_question_by_session_for_thm");
+		} else {
+			view = new NovaView("skill_question/preparation_question_by_session_for_all");
+		}
+		view.setStartKeyArray(session.get_id());
+		view.setEndKeyArray(session.get_id(), "{}");
+		return collectQuestionIds(view);
+	}
+
+	private List<String> collectUnansweredQuestionIds(Session session, User user, List<String> questions, NovaView view) {
+		ViewResults answeredQuestions = this.getDatabase().view(view);
+
+		List<String> answered = new ArrayList<String>();
+		for (Document d : answeredQuestions.getResults()) {
+			answered.add(d.getString("value"));
+		}
+
+		List<String> unanswered = new ArrayList<String>();
+		for (String questionId : questions) {
+			if (!answered.contains(questionId)) {
+				unanswered.add(questionId);
+			}
+		}
+		return unanswered;
+	}
+
+	private List<String> collectQuestionIds(NovaView view) {
+		ViewResults results = this.getDatabase().view(view);
+		if (results.getResults().size() == 0) {
+			return new ArrayList<String>();
+		}
+		List<String> ids = new ArrayList<String>();
+		for (Document d : results.getResults()) {
+			ids.add(d.getId());
+		}
+		return ids;
+	}
+	
+	public void deleteAllInterposedQuestions(Session session) {
+		NovaView view = new NovaView("interposed_question/by_session");
+		view.setKey(session.get_id());
+		ViewResults questions = this.getDatabase().view(view);
+		if (questions == null || questions.isEmpty()) {
+			return;
+		}
+		for (Document document : questions.getResults()) {
+			try {
+				this.deleteDocument(document.getId());
+			} catch (IOException e) {
+				LOGGER.error("Could not delete all interposed questions {}", session);
+			}
+		}
+	}
+
+	@Override
+	public void publishAllQuestions(Session session, boolean publish) {
+		List<Question> questions = this.getQuestions(new NovaView("skill_question/by_session"), session);
+		for (Question q : questions) {
+			q.setActive(publish);
+		}
+		List<Document> documents = new ArrayList<Document>();
+		for (Question q : questions) {
+			Document d = toQuestionDocument(session, q);
+			d.setId(q.get_id());
+			d.setRev(q.get_rev());
+			documents.add(d);
+		}
+		try {
+			this.database.bulkSaveDocuments(documents.toArray(new Document[documents.size()]));
+		} catch (IOException e) {
+			LOGGER.error("Could not bulk publish all questions: {}", e.getMessage());
+		}
+	}
+
+	@Override
+	public void deleteAllQuestionsAnswers(Session session) {
+		List<Question> questions = this.getQuestions(new NovaView("skill_question/by_session"), session);
+		for (Question q : questions) {
+			this.deleteAnswers(q);
+		}
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
index d6027c30c7a90916fbaf61aa17495890389405c4..b7f153c1f8487c8b9d2fa99fc4e0466a3f514b61 100644
--- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
+++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
@@ -48,7 +48,7 @@ public interface IDatabaseDao {
 
 	Question getQuestion(String id);
 
-	List<Question> getSkillQuestions(String session);
+	List<Question> getSkillQuestions(User user, Session session);
 
 	int getSkillQuestionCount(Session session);
 
@@ -68,14 +68,12 @@ public interface IDatabaseDao {
 
 	List<Answer> getAnswers(String questionId, int piRound);
 
-	int getAnswerCount(String questionId);
+	int getAnswerCount(Question question, int piRound);
 
 	List<Answer> getFreetextAnswers(String questionId);
 
 	int countActiveUsers(long since);
 
-	int countActiveUsers(Session session, long since);
-
 	List<Answer> getMyAnswers(String sessionKey);
 
 	int getTotalAnswerCount(String sessionKey);
@@ -128,5 +126,39 @@ public interface IDatabaseDao {
 
 	List<String> getActiveUsers(int timeDifference);
 
+	Session updateSession(Session session);
+
 	void deleteSession(Session session);
+
+	List<Question> getLectureQuestions(User user, Session session);
+
+	List<Question> getFlashcards(User user, Session session);
+
+	List<Question> getPreparationQuestions(User user, Session session);
+
+	int getLectureQuestionCount(Session session);
+
+	int getFlashcardCount(Session session);
+
+	int getPreparationQuestionCount(Session session);
+
+	int countLectureQuestionAnswers(Session session);
+
+	int countPreparationQuestionAnswers(Session session);
+
+	void deleteAllLectureQuestionsWithAnswers(Session session);
+
+	void deleteAllFlashcardsWithAnswers(Session session);
+
+	void deleteAllPreparationQuestionsWithAnswers(Session session);
+
+	List<String> getUnAnsweredLectureQuestionIds(Session session, User user);
+
+	List<String> getUnAnsweredPreparationQuestionIds(Session session, User user);
+
+	void deleteAllInterposedQuestions(Session session);
+
+	void publishAllQuestions(Session session, boolean publish);
+
+	void deleteAllQuestionsAnswers(Session session);
 }
diff --git a/src/main/java/de/thm/arsnova/entities/Answer.java b/src/main/java/de/thm/arsnova/entities/Answer.java
index 278ac92d50b61363859b23a4133e836993b331a9..aed482cfba76aac0f3f915fcba3d21b117af4579 100644
--- a/src/main/java/de/thm/arsnova/entities/Answer.java
+++ b/src/main/java/de/thm/arsnova/entities/Answer.java
@@ -9,12 +9,13 @@ public class Answer {
 	private String questionId;
 	private String answerText;
 	private String answerSubject;
+	private String questionVariant;
 	private int piRound;
 	private String user;
 	private long timestamp;
 	private int answerCount = 1;
-	private boolean abstention; // Currently available only for freetext and mc answers!
-	private int abstentionCount; // Currently available only for freetext and mc answers!
+	private boolean abstention;
+	private int abstentionCount;
 
 	public Answer() {
 		this.type = "skill_question_answer";
@@ -124,6 +125,14 @@ public class Answer {
 		this.abstentionCount = abstentionCount;
 	}
 
+	public String getQuestionVariant() {
+		return questionVariant;
+	}
+
+	public void setQuestionVariant(String questionVariant) {
+		this.questionVariant = questionVariant;
+	}
+
 	@Override
 	public final String toString() {
 		return "Answer type:'" + type + "'"
diff --git a/src/main/java/de/thm/arsnova/entities/LoggedIn.java b/src/main/java/de/thm/arsnova/entities/LoggedIn.java
index f44650438b17212e99a9183dcd038155ed714aee..1c4b91719ebaf41eb769b65fbb016a458d120555 100644
--- a/src/main/java/de/thm/arsnova/entities/LoggedIn.java
+++ b/src/main/java/de/thm/arsnova/entities/LoggedIn.java
@@ -122,7 +122,7 @@ public class LoggedIn {
 	}
 
 	public boolean hasConflicts() {
-		return ! (_conflicts == null || _conflicts.isEmpty());
+		return !(_conflicts == null || _conflicts.isEmpty());
 	}
 
 	@Override
@@ -132,4 +132,4 @@ public class LoggedIn {
 				+ ", timestamp=" + timestamp + ", visitedSessions="
 				+ visitedSessions + "]";
 	}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/de/thm/arsnova/entities/Question.java b/src/main/java/de/thm/arsnova/entities/Question.java
index de56243c017d4932b02ae8ae76fbe832d2b9045c..33c2e59a14ac3385e6f4e44cf695a80a3c0b8d47 100644
--- a/src/main/java/de/thm/arsnova/entities/Question.java
+++ b/src/main/java/de/thm/arsnova/entities/Question.java
@@ -24,6 +24,7 @@ public class Question {
 
 	private String type;
 	private String questionType;
+	private String questionVariant;
 	private String subject;
 	private String text;
 	private boolean active;
@@ -59,6 +60,14 @@ public class Question {
 		this.questionType = questionType;
 	}
 
+	public final String getQuestionVariant() {
+		return questionVariant;
+	}
+
+	public final void setQuestionVariant(final String questionVariant) {
+		this.questionVariant = questionVariant;
+	}
+
 	public final String getSubject() {
 		return subject;
 	}
diff --git a/src/main/java/de/thm/arsnova/entities/Session.java b/src/main/java/de/thm/arsnova/entities/Session.java
index 0e17a2df5bb68032853d86cc71bb4e332ea579d3..fde730e3841c8e797e794c6a8029d8892cfc0886 100644
--- a/src/main/java/de/thm/arsnova/entities/Session.java
+++ b/src/main/java/de/thm/arsnova/entities/Session.java
@@ -143,6 +143,10 @@ public class Session implements Serializable {
 		return (this.getCourseId() != null) && (!this.getCourseId().isEmpty());
 	}
 	
+	public void setCourseSession() {
+		// no op!
+	}
+	
 	@Override
 	public String toString() {
 		return "User [keyword=" + keyword+ ", type=" + type + "]";
diff --git a/src/main/java/de/thm/arsnova/events/Publisher.java b/src/main/java/de/thm/arsnova/events/Publisher.java
index c8906725eeaa6280d3a103feefa6d15ce41a8f45..ac5b64fa218f3668198e2c1ac74c64bd22de8aa3 100644
--- a/src/main/java/de/thm/arsnova/events/Publisher.java
+++ b/src/main/java/de/thm/arsnova/events/Publisher.java
@@ -1,6 +1,5 @@
 package de.thm.arsnova.events;
 
-import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
@@ -13,7 +12,7 @@ public class Publisher implements ApplicationContextAware {
 	private ApplicationContext context;
 
 	@Override
-	public void setApplicationContext(ApplicationContext c) throws BeansException {
+	public void setApplicationContext(ApplicationContext c) {
 		this.context = c;
 	}
 
diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java
index 4f04a0c73506ff5b42baaf5c87cf24e8321047a8..596d1ffd40bc9986f29f060f281bc22a597306d8 100644
--- a/src/main/java/de/thm/arsnova/services/IQuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java
@@ -37,8 +37,6 @@ public interface IQuestionService {
 
 	int getSkillQuestionCount(String sessionkey);
 
-	List<String> getQuestionIds(String sessionKey);
-
 	void deleteQuestion(String questionId);
 
 	void deleteAllQuestions(String sessionKeyword);
@@ -79,4 +77,36 @@ public interface IQuestionService {
 
 	void deleteInterposedQuestion(String questionId);
 
+	List<Question> getLectureQuestions(String sessionkey);
+
+	List<Question> getFlashcards(String sessionkey);
+
+	List<Question> getPreparationQuestions(String sessionkey);
+
+	int getLectureQuestionCount(String sessionkey);
+
+	int getFlashcardCount(String sessionkey);
+
+	int getPreparationQuestionCount(String sessionkey);
+
+	int countLectureQuestionAnswers(String sessionkey);
+
+	int countPreparationQuestionAnswers(String sessionkey);
+
+	void deleteLectureQuestions(String sessionkey);
+
+	void deleteFlashcards(String sessionkey);
+
+	void deletePreparationQuestions(String sessionkey);
+
+	List<String> getUnAnsweredLectureQuestionIds(String sessionkey);
+
+	List<String> getUnAnsweredPreparationQuestionIds(String sessionkey);
+
+	void deleteAllInterposedQuestions(String sessionKeyword);
+
+	void publishAll(String sessionkey, boolean publish);
+
+	void deleteAllQuestionsAnswers(String sessionkey);
+
 }
diff --git a/src/main/java/de/thm/arsnova/services/ISessionService.java b/src/main/java/de/thm/arsnova/services/ISessionService.java
index 7efe5e0491ac75935814e5b3af7c07b2822590ef..d868e4bc1b75c68de8986bcdb7f5bb9fb2f85f7a 100644
--- a/src/main/java/de/thm/arsnova/services/ISessionService.java
+++ b/src/main/java/de/thm/arsnova/services/ISessionService.java
@@ -42,13 +42,13 @@ public interface ISessionService {
 
 	LoggedIn registerAsOnlineUser(User user, String sessionkey);
 
-	int countActiveUsers(String sessionkey);
-
 	int countSessions(List<Course> courses);
 
 	Session setActive(String sessionkey, Boolean lock);
 
 	Session joinSession(String keyword, UUID socketId);
 
+	Session updateSession(String sessionkey, Session session);
+
 	void deleteSession(String sessionkey, User user);
 }
diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java
index 1f9d70e87685d57dccc93eab2c8afa80612a0c20..0467de78e4aa89783df70616385df70ea61b6aab 100644
--- a/src/main/java/de/thm/arsnova/services/QuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/QuestionService.java
@@ -35,7 +35,7 @@ import de.thm.arsnova.entities.InterposedReadingCount;
 import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
-import de.thm.arsnova.exceptions.NoContentException;
+import de.thm.arsnova.exceptions.ForbiddenException;
 import de.thm.arsnova.exceptions.NotFoundException;
 import de.thm.arsnova.exceptions.UnauthorizedException;
 import de.thm.arsnova.socket.ARSnovaSocketIOServer;
@@ -59,11 +59,7 @@ public class QuestionService implements IQuestionService {
 	@Override
 	@Authenticated
 	public List<Question> getSkillQuestions(String sessionkey) {
-		List<Question> result = databaseDao.getSkillQuestions(sessionkey);
-		if (result == null || result.size() == 0) {
-			throw new NoContentException();
-		}
-		return result;
+		return databaseDao.getSkillQuestions(userService.getCurrentUser(), getSession(sessionkey));
 	}
 
 	@Override
@@ -79,6 +75,12 @@ public class QuestionService implements IQuestionService {
 		Session session = this.databaseDao.getSessionFromKeyword(question.getSessionKeyword());
 		question.setSessionId(session.get_id());
 
+		User user = userService.getCurrentUser();
+
+		if (! session.isCreator(user)) {
+			throw new ForbiddenException();
+		}
+
 		if ("freetext".equals(question.getQuestionType())) {
 			question.setPiRound(0);
 		} else if (question.getPiRound() < 1 || question.getPiRound() > 2) {
@@ -110,6 +112,9 @@ public class QuestionService implements IQuestionService {
 	@Authenticated
 	public Question getQuestion(String id) {
 		Question result = databaseDao.getQuestion(id);
+		if (result == null) {
+			return null;
+		}
 		if (!"freetext".equals(result.getQuestionType()) && 0 == result.getPiRound()) {
 			/* needed for legacy questions whose piRound property has not been set */
 			result.setPiRound(1);
@@ -118,20 +123,6 @@ public class QuestionService implements IQuestionService {
 		return result;
 	}
 
-	@Override
-	@Authenticated
-	public List<String> getQuestionIds(String sessionKey) {
-		User user = userService.getCurrentUser();
-		if (user == null) {
-			throw new UnauthorizedException();
-		}
-		Session session = databaseDao.getSessionFromKeyword(sessionKey);
-		if (session == null) {
-			throw new NotFoundException();
-		}
-		return databaseDao.getQuestionIds(session, user);
-	}
-
 	@Override
 	@Authenticated
 	public void deleteQuestion(String questionId) {
@@ -142,7 +133,7 @@ public class QuestionService implements IQuestionService {
 
 		User user = userService.getCurrentUser();
 		Session session = databaseDao.getSession(question.getSessionKeyword());
-		if (user == null || session == null || !session.isCreator(user)) {
+		if (user == null || session == null || ! session.isCreator(user)) {
 			throw new UnauthorizedException();
 		}
 		databaseDao.deleteQuestionWithAnswers(question);
@@ -151,12 +142,17 @@ public class QuestionService implements IQuestionService {
 	@Override
 	@Authenticated
 	public void deleteAllQuestions(String sessionKeyword) {
+		Session session = getSessionWithAuthCheck(sessionKeyword);
+		databaseDao.deleteAllQuestionsWithAnswers(session);
+	}
+
+	private Session getSessionWithAuthCheck(String sessionKeyword) {
 		User user = userService.getCurrentUser();
 		Session session = databaseDao.getSession(sessionKeyword);
-		if (user == null || session == null || !session.isCreator(user)) {
+		if (user == null || session == null || ! session.isCreator(user)) {
 			throw new UnauthorizedException();
 		}
-		databaseDao.deleteAllQuestionsWithAnswers(session);
+		return session;
 	}
 
 	@Override
@@ -168,11 +164,22 @@ public class QuestionService implements IQuestionService {
 		}
 		User user = userService.getCurrentUser();
 		Session session = databaseDao.getSessionFromKeyword(question.getSessionId());
-		if (user == null || session == null || !session.isCreator(user)) {
+		if (user == null || session == null || ! session.isCreator(user)) {
 			throw new UnauthorizedException();
 		}
 		databaseDao.deleteInterposedQuestion(question);
 	}
+	
+	@Override
+	@Authenticated
+	public void deleteAllInterposedQuestions(String sessionKeyword) {
+		User user = userService.getCurrentUser();
+		Session session = databaseDao.getSessionFromKeyword(sessionKeyword);
+		if (user == null || session == null || ! session.isCreator(user)) {
+			throw new UnauthorizedException();
+		}
+		databaseDao.deleteAllInterposedQuestions(session);
+	}
 
 	@Override
 	@Authenticated
@@ -184,7 +191,7 @@ public class QuestionService implements IQuestionService {
 
 		User user = userService.getCurrentUser();
 		Session session = databaseDao.getSession(question.getSessionKeyword());
-		if (user == null || session == null || !session.isCreator(user)) {
+		if (user == null || session == null || ! session.isCreator(user)) {
 			throw new UnauthorizedException();
 		}
 		databaseDao.deleteAnswers(question);
@@ -193,15 +200,17 @@ public class QuestionService implements IQuestionService {
 	@Override
 	@Authenticated
 	public List<String> getUnAnsweredQuestionIds(String sessionKey) {
+		User user = getCurrentUser();
+		Session session = getSession(sessionKey);
+		return databaseDao.getUnAnsweredQuestionIds(session, user);
+	}
+
+	private User getCurrentUser() {
 		User user = userService.getCurrentUser();
 		if (user == null) {
 			throw new UnauthorizedException();
 		}
-		Session session = databaseDao.getSessionFromKeyword(sessionKey);
-		if (session == null) {
-			throw new NotFoundException();
-		}
-		return databaseDao.getUnAnsweredQuestionIds(session, user);
+		return user;
 	}
 
 	@Override
@@ -230,11 +239,12 @@ public class QuestionService implements IQuestionService {
 		return getAnswers(questionId, question.getPiRound());
 	}
 
-	/* TODO add implementation for piRound */
 	@Override
 	@Authenticated
 	public int getAnswerCount(String questionId) {
-		return databaseDao.getAnswerCount(questionId);
+		Question question = getQuestion(questionId);
+		
+		return databaseDao.getAnswerCount(question, question.getPiRound());
 	}
 
 	@Override
@@ -342,10 +352,7 @@ public class QuestionService implements IQuestionService {
 	@Override
 	@Authenticated
 	public Answer saveAnswer(Answer answer) {
-		User user = userService.getCurrentUser();
-		if (user == null) {
-			throw new UnauthorizedException();
-		}
+		User user = getCurrentUser();
 		Question question = this.getQuestion(answer.getQuestionId());
 		if (question == null) {
 			throw new NotFoundException();
@@ -386,7 +393,7 @@ public class QuestionService implements IQuestionService {
 			throw new NotFoundException();
 		}
 		User user = userService.getCurrentUser();
-		Session session = this.databaseDao.getSessionFromId(question.getSessionId());
+		Session session = this.databaseDao.getSessionFromKeyword(question.getSessionKeyword());
 		if (user == null || session == null || !session.isCreator(user)) {
 			throw new UnauthorizedException();
 		}
@@ -394,4 +401,119 @@ public class QuestionService implements IQuestionService {
 
 		socketIoServer.reportAnswersToLecturerQuestionAvailable(question.getSessionKeyword(), question.get_id());
 	}
+
+	@Override
+	@Authenticated
+	public List<Question> getLectureQuestions(String sessionkey) {
+		return databaseDao.getLectureQuestions(userService.getCurrentUser(), getSession(sessionkey));
+	}
+
+	@Override
+	@Authenticated
+	public List<Question> getFlashcards(String sessionkey) {
+		return databaseDao.getFlashcards(userService.getCurrentUser(), getSession(sessionkey));
+	}
+
+	@Override
+	@Authenticated
+	public List<Question> getPreparationQuestions(String sessionkey) {
+		return databaseDao.getPreparationQuestions(userService.getCurrentUser(), getSession(sessionkey));
+	}
+	
+	private Session getSession(String sessionkey) {
+		Session session = this.databaseDao.getSessionFromKeyword(sessionkey);
+		if (session == null) {
+			throw new NotFoundException();
+		}
+		return session;
+	}
+
+	@Override
+	@Authenticated
+	public int getLectureQuestionCount(String sessionkey) {
+		return databaseDao.getLectureQuestionCount(getSession(sessionkey));
+	}
+
+	@Override
+	@Authenticated
+	public int getFlashcardCount(String sessionkey) {
+		return databaseDao.getFlashcardCount(getSession(sessionkey));
+	}
+
+	@Override
+	@Authenticated
+	public int getPreparationQuestionCount(String sessionkey) {
+		return databaseDao.getPreparationQuestionCount(getSession(sessionkey));
+	}
+
+	@Override
+	@Authenticated
+	public int countLectureQuestionAnswers(String sessionkey) {
+		return databaseDao.countLectureQuestionAnswers(getSession(sessionkey));
+	}
+
+	@Override
+	@Authenticated
+	public int countPreparationQuestionAnswers(String sessionkey) {
+		return databaseDao.countPreparationQuestionAnswers(getSession(sessionkey));
+	}
+
+	@Override
+	@Authenticated
+	public void deleteLectureQuestions(String sessionkey) {
+		Session session = getSessionWithAuthCheck(sessionkey);
+		databaseDao.deleteAllLectureQuestionsWithAnswers(session);
+	}
+
+	@Override
+	@Authenticated
+	public void deleteFlashcards(String sessionkey) {
+		Session session = getSessionWithAuthCheck(sessionkey);
+		databaseDao.deleteAllFlashcardsWithAnswers(session);
+	}
+
+	@Override
+	@Authenticated
+	public void deletePreparationQuestions(String sessionkey) {
+		Session session = getSessionWithAuthCheck(sessionkey);
+		databaseDao.deleteAllPreparationQuestionsWithAnswers(session);
+	}
+
+	@Override
+	@Authenticated
+	public List<String> getUnAnsweredLectureQuestionIds(String sessionkey) {
+		User user = getCurrentUser();
+		Session session = getSession(sessionkey);
+		return databaseDao.getUnAnsweredLectureQuestionIds(session, user);
+	}
+
+	@Override
+	@Authenticated
+	public List<String> getUnAnsweredPreparationQuestionIds(String sessionkey) {
+		User user = getCurrentUser();
+		Session session = getSession(sessionkey);
+		return databaseDao.getUnAnsweredPreparationQuestionIds(session, user);
+	}
+
+	@Override
+	@Authenticated
+	public void publishAll(String sessionkey, boolean publish) {
+		User user = getCurrentUser();
+		Session session = getSession(sessionkey);
+		if (!session.isCreator(user)) {
+			throw new UnauthorizedException();
+		}
+		databaseDao.publishAllQuestions(session, publish);
+	}
+
+	@Override
+	@Authenticated
+	public void deleteAllQuestionsAnswers(String sessionkey) {
+		User user = getCurrentUser();
+		Session session = getSession(sessionkey);
+		if (!session.isCreator(user)) {
+			throw new UnauthorizedException();
+		}
+		databaseDao.deleteAllQuestionsAnswers(session);
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/services/SessionService.java b/src/main/java/de/thm/arsnova/services/SessionService.java
index 2843b36e72bfef48660f5b8fa2d861c536bc3dd1..e9e6af9b97eb11a115f681484eebdfca9a5ecc57 100644
--- a/src/main/java/de/thm/arsnova/services/SessionService.java
+++ b/src/main/java/de/thm/arsnova/services/SessionService.java
@@ -45,8 +45,6 @@ import de.thm.arsnova.socket.ARSnovaSocketIOServer;
 @Service
 public class SessionService implements ISessionService {
 
-	private static final int DURATION_IN_MILLIS = 3 * 60 * 1000;
-
 	@Autowired
 	private IDatabaseDao databaseDao;
 
@@ -196,13 +194,6 @@ public class SessionService implements ISessionService {
 		return databaseDao.registerAsOnlineUser(user, session);
 	}
 
-	@Override
-	public int countActiveUsers(String sessionkey) {
-		final long since = System.currentTimeMillis() - DURATION_IN_MILLIS;
-		Session session = databaseDao.getSessionFromKeyword(sessionkey);
-		return databaseDao.countActiveUsers(session, since);
-	}
-
 	public static class SessionNameComperator implements Comparator<Session>, Serializable {
 		private static final long serialVersionUID = 1L;
 
@@ -233,9 +224,26 @@ public class SessionService implements ISessionService {
 	@Override
 	public Session setActive(String sessionkey, Boolean lock) {
 		Session session = databaseDao.getSessionFromKeyword(sessionkey);
+		User user = userService.getCurrentUser();
+		if (!session.isCreator(user)) {
+			throw new ForbiddenException();
+		}
 		return databaseDao.lockSession(session, lock);
 	}
 
+	@Override
+	@Authenticated
+	public Session updateSession(String sessionkey, Session session) {
+		Session s = databaseDao.getSession(sessionkey);
+		User user = userService.getCurrentUser();
+
+		if (!s.isCreator(user)) {
+			throw new ForbiddenException();
+		}
+
+		return databaseDao.updateSession(session);
+	}
+
 	@Override
 	@Authenticated
 	public void deleteSession(String sessionkey, User user) {
@@ -243,7 +251,7 @@ public class SessionService implements ISessionService {
 		if (!session.isCreator(user)) {
 			throw new ForbiddenException();
 		}
-		for (Question q : databaseDao.getSkillQuestions(sessionkey)) {
+		for (Question q : databaseDao.getSkillQuestions(user, session)) {
 			databaseDao.deleteQuestionWithAnswers(q);
 		}
 		databaseDao.deleteSession(session);
diff --git a/src/main/java/de/thm/arsnova/services/UserSessionService.java b/src/main/java/de/thm/arsnova/services/UserSessionService.java
index df3110cd50221cba01a1dc79b7ddb1951271091a..170030f67b8e6076203f9b2f2f780be73f8f45e3 100644
--- a/src/main/java/de/thm/arsnova/services/UserSessionService.java
+++ b/src/main/java/de/thm/arsnova/services/UserSessionService.java
@@ -30,4 +30,4 @@ public interface UserSessionService {
 	boolean isAuthenticated();
 	
 	void sendEventViaWebSocket(ARSnovaSocketIOServer server, ARSnovaEvent event);
-}
\ No newline at end of file
+}
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
index f9d41fcd95e3c1052b9ffc906ecb69424a3cc0bf..d63372fa8b4155a7a0f24d16e70b3f2422db5c24 100644
--- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
@@ -109,7 +109,7 @@ public class ARSnovaSocketIOServer {
 				 * a feedback
 				 */
 				User u = userService.getUser2SocketId(client.getSessionId());
-				if (u == null || ! userService.isUserInSession(u, data.getSessionkey())) {
+				if (u == null || !userService.isUserInSession(u, data.getSessionkey())) {
 					return;
 				}
 				feedbackService.saveFeedback(data.getSessionkey(), data.getValue(), u);
@@ -310,11 +310,11 @@ public class ARSnovaSocketIOServer {
 	 * 
 	 * @param sessionId The UUID of the websocket ID
 	 * @param event The event to be send to client
+	 * TODO This method is unimplemented!
 	 */
 	public void sendToClient(UUID sessionId, ARSnovaEvent event) {
 		for (SocketIOClient c : server.getAllClients()) {
 			if (c.getSessionId().equals(sessionId)) {
-				System.out.println(sessionId);
 				break;
 			}
 		}
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index e89e459cce18e80dd33f993f4ae9cf1527d7503d..8ebba29fa000ab97ff476a88dd6dc00bcb439785 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -62,6 +62,10 @@
 		<extension>manifest</extension>
 		<mime-type>text/cache-manifest</mime-type>
 	</mime-mapping>
+	<mime-mapping>
+		<extension>json</extension>
+		<mime-type>application/json</mime-type>
+	</mime-mapping>
 
 	<error-page>
 		<error-code>401</error-code>
@@ -81,6 +85,8 @@
 	</error-page>
 
 	<session-config>
+		<tracking-mode>COOKIE</tracking-mode>
+
 		<!-- delete sessions after 6 hours -->
 		<session-timeout>360</session-timeout>
 	</session-config>
diff --git a/src/main/webapp/arsnova.properties.example b/src/main/webapp/arsnova.properties.example
index 4e4a13edb3a7208c75d1bcb1c08f0edddbfa01fb..0db2d28970d6ebec47466294b361b4c7443f9ea3 100644
--- a/src/main/webapp/arsnova.properties.example
+++ b/src/main/webapp/arsnova.properties.example
@@ -25,10 +25,12 @@ feedback.cleanup=10
 couchdb.host=localhost
 couchdb.port=5984
 couchdb.name=arsnova
+couchdb.username=admin
+couchdb.password=
 
 socketio.ip=0.0.0.0
 socketio.port=10443
 
 connector.uri=http://localhost:8080/connector-service
 connector.username=test
-connector.password=test
\ No newline at end of file
+connector.password=test
diff --git a/src/site/apt/development.apt b/src/site/apt/development.apt
deleted file mode 100644
index a03c524381d5be473e1b760983413912737ae7d1..0000000000000000000000000000000000000000
--- a/src/site/apt/development.apt
+++ /dev/null
@@ -1,127 +0,0 @@
- -------------------
- ARSnova Development
- -------------------
- -------------------
- ARSnova Developers
- -------------------
- 2013-03-11
-
-Development
-
- This short guide will help you get your development environment up and running. In brief, here is the list of the required tools:
- 
- 	* Apache HTTP Server
- 
-	* Apache Maven
-
-	* Git
-	
-	* Apache CouchDB
-	
-	* ARSnova
-	
-	ARSnova consists of several sub projects. The first one is the project you're currently looking at. All projects except for 'arsnova-war' are optional: you don't need to download them if you do not plan to work with them.
-	
-		* arsnova-war (this project)
-		
-		* arsnova-legacy-js
-		
-		* arsnova-js
-		
-		* arsnova-st2-js
-		
-		* setuptool
-		
-		* connector (manual installation is currently required in order to run 'arsnova-war')
-	
-	* Sonar and Sonar Runner
-	
-		* JavaScript Plugin
-		
-	* Eclipse JEE
- 
-	Install the following plugins from the Eclipse Marketplace:
-	
-		* Maven WTP
-	
-		* EGit
-	
-		* Sonar
-	
-		* Checkstyle
-		
- A note to all Windows users: We did not test this documentation on any Windows machine, so your mileage will certainly vary.
-
-* Apache HTTP Server
-
- The best option is to use your distribution's package manager to install your first piece of software: the Apache HTTP Server. For now, no additional configuration is necessary.
-		
-* Apache Maven
-
- As you might have noticed, ARSnova and its tools require a JDK. So go ahead and install it from your favorite package manager if you haven't already.
- 
- Download Maven and follow the installation instructions: {{http://maven.apache.org/download.cgi}}
- 
-* Git
-
- Install Git via your package manager. Windows users might want to try {{{http://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git}msysgit}}.
- 
-* Apache CouchDB
-
- Again, the best way is to use your package manager to install CouchDB. Additionally, some binaries are available at {{http://couchdb.apache.org}}.
- 
-* ARSnova
-
- Head over to {{https://scm.thm.de/arsnova}}. Here you'll find all ARSnova repositories. You could now either clone them directly onto your machine, or create a personal clone first ('Clone repository' button). The first option will usually suffice, and you may create a personal clone later at any time.
- 
- It's best to first create an ARSnova project folder. Inside this folder clone all of the following repositories:
- 
- 	* arsnova-war
-	
-	* arsnova-legacy-js
-	
-	* arsnova-st2-js
-	
-	* arsnova-js
-	
-	* setuptool
-	
-	* connector
-
- A folder for each project will be created during checkout.	
- 
- Now is a good time to check if you configured your Git client correctly. Type in the commands 'git config --global user.name' and 'git config --global user.email', and verify they return the values you want. By leaving out the '--global' part while being inside a folder with a Git repository, the settings will be specific to this repository.
- 
- The next task is to configure ARSnova according to the {{{installation.html}installation manual}}.
- 
- As we're going to modify the local CouchDB, make sure you also specify the properties 'couchdb.username' and 'couchdb.password'; they are not present in the example properties file. Either put in your CouchDB credentials, or leave them blank if you did follow this guide step by step.
- 
- If your system has Python installed, head into the 'setuptool' project and run 'python tool.py' to automatically set up the CouchDB database and all views. If Python is not available, you will need to execute this project from Eclipse.
- 
- Finally, by running 'mvn install' inside each repository you will compile, test and install the project into your local Maven repository. This step is not required, but it will show if everything is set up correctly.
- 
- Note: If you get build failures because the 'connector' dependency could not be resolved, you have to manually 'mvn install' the 'connector'.
- 
-* Sonar
-
- Use your package manager to install Sonar and Sonar Runner, or follow the instructions at {{http://docs.codehaus.org/display/SONAR/Installing+Sonar}}. Once both are installed start the Sonar server if it is not yet running, then go to {{http://localhost:9000}}, and click 'Log in' (located in the far right corner). Username and password both are 'admin'. Then, click on 'Settings' and select 'System'. In the menu on the left you can then select 'Update Center'. Now, change to 'Available Plugins' and search for JavaScript. Click the name and then click Install. A restart of Sonar is required to finish the installation process.
- 
-* Eclipse
-
- For our IDE we chose Eclipse JEE: {{http://www.eclipse.org/downloads/}}
- 
- Unpack it into a folder of your choice. Run Eclipe, and then open the Eclipse Marketplace; it's located in the Help menu. There, search and install the following plugins (you might have to restart Eclipse several times along the way):
- 
- 	* m2e-wtp
-	
-	* EGit (might already be installed)
-	
-	* Sonar (you might want to deselect the Python and C/C++ analyzers)
-	
-	* Checkstyle
-	
- Next, you're going to import each project into the workspace. Select 'Import...' from the File menu, open the 'Maven' category, and select 'Existing Maven Projects'. Browse into a project you cloned previously, checkmark the project as it appears and click finish. Repeat for every project you want to develop for.
- 
- For Checkstyle support in 'arsnova-war', right click the project, open the properties, and select the Checkstyle category. Switch to the 'Local Check Configurations' tab, and for 'Type' select 'External Configuration File'. Give it a name (eg. 'ARSnova'), then browse into the project's folder, and select 'ARSnova-checkstyle-checker.xml'. When you click on 'OK', you will get an error message. But don't worry, just click on 'Edit properties...' and follow the instructions. An empty property for a cache file will get created, and you need to enter a file name of your choice. Now Close all dialogs. To test drive Checkstyle right clicking on the project and select 'Check Code with Checkstyle' from the 'Checkstyle' menu.
- 
- And that's it! If you have spotted any mistakes please let us know.
\ No newline at end of file
diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt
index 0de3f466fa60e79e2162c6808ee9f3adb955a7ec..3cb05dc4ca849716242dd9978f95514530cc1eb8 100644
--- a/src/site/apt/index.apt
+++ b/src/site/apt/index.apt
@@ -14,7 +14,7 @@ ARSnova
 	
 	* {{{https://scm.thm.de/redmine/documents/16}Präsentation über ARSnova}}
 	
-	* {{{https://ars.thm.de/download/}Desktop-Widget}}
+	* {{{https://arsnova.eu/overlay/}Desktop-Widget}}
 	
 	* {{{http://prezi.com/bkfz1utyaiiw/arsnova/}ARSnova auf Prezi}}
 
diff --git a/src/site/apt/installation.apt b/src/site/apt/installation.apt
deleted file mode 100644
index e30cf7011119154090972cc365713a56e487b5e9..0000000000000000000000000000000000000000
--- a/src/site/apt/installation.apt
+++ /dev/null
@@ -1,111 +0,0 @@
- -----
- Installation Instructions
- -----
- ARSnova Developers
- -----
- -----
-
- 
-Deployment
-
- You will need to do some configuration work upfront.
-
-  * Add a new directory "arsnova" in /etc and create a copy of arsnova.properties.example named arsnova.properties in this directory.
-  
-  * Change settings to match your environment
-
-Server configuration
-
- In order to build up a full featured server installation containing ARSnova2 and CouchDB you have to install at least the following services:
-  
-  * Apache Tomcat 7.0.29 (or newer)
-  
-  * Apache Webserver 2.2 or newer with buildin mod_proxy, mod_proxy_ajp and mod_proxy_http
-  
-  * Apache CouchDB
- 
- Make sure all services are installed. Next step is to configure the Apache Webserver. Find the configuration file or create a new one for use with a virtal host. This depends on your needs. At least you should have a configuration containing these settings:
-
-+--------------------------------------------------------+
-	
-	<Location /couchdb/>
-		ProxyPass http://127.0.0.1:5984/
-		ProxyPassReverse http://127.0.0.1:5984/
-	</Location> 
-	
-	<Location />
-		ProxyPass ajp://127.0.0.1:8009/
-		ProxyPassReverse ajp://127.0.0.1:8009/
-	</Location>
-	
-+--------------------------------------------------------+
-
- This will redirect all requests for "/couchdb/..." to your Apache CouchDB server, running on port 5984.
- All other requests will be send to your Apache Tomcat servelt container, using AJP running on port 8009.
-
- To enable the needed Apache Webserver simply type:
-
-+---------------------------+
- 
-  # a2enmod proxy
-  # a2enmod proxy_ajp
-  # a2enmod proxy_http
- 
-+---------------------------+
-
- The configuration is ready for development usage. You should (re)start all services. ARSnova2 is now listening on HTTP port 80.
-
-Make environment usable for productive usage
-
- If you intend to use ARSnova in productive environment, you will have to change a setting in your Tomcat installation.
- Look for your Tomcat configuration directory and change the file "context.xml" to match this example:
- 
-+---------------------------+
- 
-<Context>
-	<Manager pathname="<...your_tomcat_installation...>/sessions/arsnova.ser"/>
-</Context> 
- 
-+---------------------------+
- 
- This will enable session persistance across restarts as described {{{http://tomcat.apache.org/tomcat-7.0-doc/config/manager.html#Special_Features}here}}.
-
- To protect requests and responses you should use HTTPS and configure your Apache Webserver installation to redirect all traffic according to this
- {{{http://wiki.apache.org/httpd/RedirectSSL}example}}.
-
- Finally you should (re)start all services. ARSnova2 is now listening on HTTP port 80 and 443.
- 
-Securing your websocket connection
-
- To provide SSL websocket encryption, you have to provide the servers ssl key and certificate in a Java keystore. The following steps will guide you threw this process.
- 
- Use your webserver certificate, private key and certificate chain to create a PKCS12 keystore
-
-+---------------------------+
-openssl pkcs12 -export -in <servercert>.crt -inkey <serverkey>.key \
-               -out keystore.p12 -name 1 \
-               -certfile <your_cert_chain_file>
-+---------------------------+
-
- You will be asked for a password for your PKCS12 keystore. This password must be used for importing this keystore into your java keystore.
- The import can be done by using this command:
-
-+---------------------------+
-keytool -importkeystore \
-        -deststorepass <your_java_keystore_password> -destkeypass <your_java_keystore_password> -destkeystore arsnova.jks \
-        -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass <your_pkcs12_keystore_password> \
-        -alias 1
-+---------------------------+
- 
- Be sure to provide the correct certificate and key file names and to use the correct passwords for your keystore.
- 
- The last step is to find your ARSnova configuration file, setup the location of your Java keystore and its password.
- 
-+---------------------------+
- 
-security.ssl=true
-security.keystore=<your keystore location>
-security.storepass=<your keystore password>
- 
-+---------------------------+
- 
\ No newline at end of file
diff --git a/src/site/site.xml b/src/site/site.xml
index c29364d8c13c22a3d033de91e8b5119873d37e80..cd6bc92b515e5b3f9771b9086524777e607b241d 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 
-<project name="ARSNova" xmlns="http://maven.apache.org/DECORATION/1.0.0"
+<project name="ARSnova" xmlns="http://maven.apache.org/DECORATION/1.0.0"
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
 
@@ -50,8 +50,8 @@
 			<item name="The Team" href="team-list.html" />
 		</menu>
 		<menu name="Documentation">
-			<item name="Installation" href="installation.html" />
-			<item name="Development" href="development.html" />
+			<item name="Installation" href="https://github.com/thm-projects/arsnova-war#production-use" />
+			<item name="Development" href="https://github.com/thm-projects/arsnova-war#development" />
 			<item name="Dependencies" href="dependencies.html" />
 			<item name="API Docs" href="apidocs/index.html" />
 		</menu>
diff --git a/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java b/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java
index 9a9ef5bd836eaa7b38e0ddf22ea5fa47a3befca4..2cf9ff61f7e5e1648aac2f3515ece81861628885 100644
--- a/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java
+++ b/src/test/java/de/thm/arsnova/controller/FeedbackControllerTest.java
@@ -20,7 +20,6 @@ import org.springframework.web.servlet.HandlerAdapter;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
 
-import de.thm.arsnova.FeedbackStorage;
 import de.thm.arsnova.dao.StubDatabaseDao;
 import de.thm.arsnova.exceptions.NoContentException;
 import de.thm.arsnova.exceptions.NotFoundException;
@@ -49,8 +48,6 @@ public class FeedbackControllerTest {
 	@Autowired
 	private StubDatabaseDao databaseDao;
 	
-	private FeedbackStorage feedbackStorage;
-
 	@After
 	public final void cleanup() {
 		databaseDao.cleanupTestData();
@@ -61,7 +58,6 @@ public class FeedbackControllerTest {
 		this.request = new MockHttpServletRequest();
 		this.response = new MockHttpServletResponse();
 		handlerAdapter = applicationContext.getBean(AnnotationMethodHandlerAdapter.class);
-		this.feedbackStorage = new FeedbackStorage(databaseDao); 
 	}
 
 	@Test(expected = NotFoundException.class)
diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
index 5f83db6dbe0650196b6c90c5b202437bc019c53b..8e354540801597bbedda9e3cf505295dcf207b4f 100644
--- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
+++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
@@ -172,8 +172,8 @@ public class StubDatabaseDao implements IDatabaseDao {
 	}
 
 	@Override
-	public List<Question> getSkillQuestions(String session) {
-		if (getSession(session) == null)
+	public List<Question> getSkillQuestions(User user, Session session) {
+		if (session == null)
 			throw new NotFoundException();
 		List<Question> questions = stubQuestions.get(session);
 		if (questions == null)
@@ -217,7 +217,7 @@ public class StubDatabaseDao implements IDatabaseDao {
 	}
 
 	@Override
-	public int getAnswerCount(String questionId) {
+	public int getAnswerCount(Question question, int piRound) {
 		// TODO Auto-generated method stub
 		return 0;
 	}
@@ -274,12 +274,6 @@ public class StubDatabaseDao implements IDatabaseDao {
 		return null;
 	}
 
-	@Override
-	public int countActiveUsers(Session session, long since) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
 	@Override
 	public int countAnswers() {
 		// TODO Auto-generated method stub
@@ -393,6 +387,12 @@ public class StubDatabaseDao implements IDatabaseDao {
 		return null;
 	}
 
+	@Override
+	public Session updateSession(Session session) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
 	@Override
 	public void deleteSession(Session session) {
 		// TODO Auto-generated method stub
@@ -403,4 +403,98 @@ public class StubDatabaseDao implements IDatabaseDao {
 		// TODO Auto-generated method stub
 		
 	}
+
+	@Override
+	public List<Question> getLectureQuestions(User user, Session session) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<Question> getFlashcards(User user, Session session) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<Question> getPreparationQuestions(User user, Session session) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public int getLectureQuestionCount(Session session) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int getFlashcardCount(Session session) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int getPreparationQuestionCount(Session session) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int countLectureQuestionAnswers(Session session) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int countPreparationQuestionAnswers(Session session) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void deleteAllLectureQuestionsWithAnswers(Session session) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void deleteAllFlashcardsWithAnswers(Session session) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void deleteAllPreparationQuestionsWithAnswers(Session session) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public List<String> getUnAnsweredLectureQuestionIds(Session session, User user) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<String> getUnAnsweredPreparationQuestionIds(Session session, User user) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void deleteAllInterposedQuestions(Session session) {
+		// TODO Auto-generated method stub
+	}
+
+	@Override
+	public void publishAllQuestions(Session session, boolean publish) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void deleteAllQuestionsAnswers(Session session) {
+		// TODO Auto-generated method stub
+		
+	}
 }
diff --git a/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java b/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java
index e96de49ee2e1a51b206a68e319cf8566f49f652f..06409e42b480b04fc1cf9118e84534722672967f 100644
--- a/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java
+++ b/src/test/java/de/thm/arsnova/services/FeedbackServiceTest.java
@@ -166,9 +166,6 @@ public class FeedbackServiceTest {
 	public static class TestUser extends User {
 		private static final long serialVersionUID = 1L;
 		
-		private String username;
-		private String type;
-
 		public TestUser(String username) {
 			super( new UsernamePasswordAuthenticationToken(username, "secret") );
 		}
diff --git a/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java b/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java
index a78e67a1749853f061c92849ccc78d53e41a2a21..96e81937abb951675eff7769f6301a30db4a638e 100644
--- a/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java
+++ b/src/test/java/de/thm/arsnova/services/QuestionServiceTest.java
@@ -101,10 +101,4 @@ public class QuestionServiceTest {
 		
 		assertFalse(theQ.isRead());
 	}
-
-	@Test
-	public void testShouldNotThrowExceptionInMyAnsersCall() {
-		userService.setUserAuthenticated(true);
-		assertNotNull(questionService.getMyAnswers("12345678"));
-	}
 }
diff --git a/src/test/java/de/thm/arsnova/services/SessionServiceTest.java b/src/test/java/de/thm/arsnova/services/SessionServiceTest.java
index c6ede4f8dfd05792f6996ab9a81aed41f0cb3a35..06956f115a28b51d14b39d478183e94d3e23e14d 100644
--- a/src/test/java/de/thm/arsnova/services/SessionServiceTest.java
+++ b/src/test/java/de/thm/arsnova/services/SessionServiceTest.java
@@ -67,7 +67,6 @@ public class SessionServiceTest {
 	
 	@Test
 	public void testShouldGenerateSessionKeyword() {
-		System.out.println(sessionService.generateKeyword());
 		assertTrue(sessionService.generateKeyword().matches("^[0-9]{8}$"));
 	}
 
@@ -126,7 +125,7 @@ public class SessionServiceTest {
 			Question q2 = new Question();
 	
 			IDatabaseDao mockDatabase = mock(IDatabaseDao.class);
-			when(mockDatabase.getSkillQuestions(anyString())).thenReturn(Arrays.asList(q1, q2));
+			when(mockDatabase.getSkillQuestions(userService.getCurrentUser(), session)).thenReturn(Arrays.asList(q1, q2));
 			when(mockDatabase.getSession(anyString())).thenReturn(session);
 			ReflectionTestUtils.setField(getTargetObject(sessionService), "databaseDao", mockDatabase);