diff --git a/ma-impl.sublime-workspace b/ma-impl.sublime-workspace
index 41ee82891d2c16a876e09eb175a776a51090d10e..5c7ab3970c0c00b24f4e3162b9331b1591fb1b92 100644
--- a/ma-impl.sublime-workspace
+++ b/ma-impl.sublime-workspace
@@ -271,22 +271,6 @@
 	},
 	"buffers":
 	[
-		{
-			"file": "Vagrantfile",
-			"settings":
-			{
-				"buffer_size": 955,
-				"line_ending": "Unix"
-			}
-		},
-		{
-			"contents": "",
-			"settings":
-			{
-				"buffer_size": 0,
-				"line_ending": "Unix"
-			}
-		}
 	],
 	"build_system": "",
 	"build_system_choices":
@@ -466,16 +450,17 @@
 	"expanded_folders":
 	[
 		"/home/eike/Repositories/fu/ss15/ma/impl",
-		"/home/eike/Repositories/fu/ss15/ma/impl/vm"
+		"/home/eike/Repositories/fu/ss15/ma/impl/vm",
+		"/home/eike/Repositories/fu/ss15/ma/impl/vm/data"
 	],
 	"file_history":
 	[
+		"/home/eike/Repositories/fu/ss15/ma/impl/vm/data/data.json",
+		"/home/eike/Repositories/fu/ss15/ma/impl/vm/data/test-2.json",
+		"/home/eike/Repositories/fu/ss15/ma/impl/vm/data/test-1.json",
 		"/home/eike/.cache/.fr-rPaUI0/LICENSE.txt",
 		"/home/eike/Repositories/fu/ss15/ma/impl/vipra-rest/src/main/resources/log4j2.xml",
 		"/home/eike/Repositories/fu/ss15/ma/impl/vipra-config/log4j2.xml",
-		"/home/eike/Repositories/fu/ss15/ma/impl/vm/data/test-1.json",
-		"/home/eike/Repositories/fu/ss15/ma/impl/vm/data/test-2.json",
-		"/home/eike/Repositories/fu/ss15/ma/impl/vm/data/data.json",
 		"/home/eike/Repositories/fu/ss15/ma/impl/vipra-cmd/test/test-1.json",
 		"/home/eike/Repositories/fu/ss15/ma/impl/vipra-cmd/vipra-cmd.sh",
 		"/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/components/article-list.js",
@@ -634,6 +619,9 @@
 		"case_sensitive": false,
 		"find_history":
 		[
+			"00:00Z\" },",
+			"{ \"$date\": ",
+			".000+0000",
 			"json-api",
 			"\"id\":.*?\\n    ",
 			"\"id\":.*?\\n",
@@ -758,17 +746,17 @@
 			"redirect_intended",
 			"amount-in",
 			"'",
-			"!important",
-			"images",
-			"url(\"../images/",
-			"fa-var"
+			"!important"
 		],
 		"highlight": true,
 		"in_selection": false,
 		"preserve_case": false,
-		"regex": true,
+		"regex": false,
 		"replace_history":
 		[
+			"00:00Z\",",
+			"",
+			"Z",
 			"",
 			"\"id\":",
 			"000+0000\"",
@@ -893,10 +881,7 @@
 			"survey",
 			"SurveysController",
 			"",
-			"/assets",
-			"Config::get",
-			"Lang::t",
-			"@__"
+			"/assets"
 		],
 		"reverse": false,
 		"show_context": true,
@@ -907,190 +892,8 @@
 	"groups":
 	[
 		{
-			"selected": 1,
 			"sheets":
 			[
-				{
-					"buffer": 0,
-					"file": "Vagrantfile",
-					"semi_transient": true,
-					"settings":
-					{
-						"buffer_size": 955,
-						"regions":
-						{
-						},
-						"selection":
-						[
-							[
-								955,
-								955
-							]
-						],
-						"settings":
-						{
-							"BracketHighlighterBusy": false,
-							"bh_regions":
-							[
-								"bh_square",
-								"bh_square_center",
-								"bh_square_open",
-								"bh_square_close",
-								"bh_square_content",
-								"bh_default",
-								"bh_default_center",
-								"bh_default_open",
-								"bh_default_close",
-								"bh_default_content",
-								"bh_single_quote",
-								"bh_single_quote_center",
-								"bh_single_quote_open",
-								"bh_single_quote_close",
-								"bh_single_quote_content",
-								"bh_round",
-								"bh_round_center",
-								"bh_round_open",
-								"bh_round_close",
-								"bh_round_content",
-								"bh_tag",
-								"bh_tag_center",
-								"bh_tag_open",
-								"bh_tag_close",
-								"bh_tag_content",
-								"bh_double_quote",
-								"bh_double_quote_center",
-								"bh_double_quote_open",
-								"bh_double_quote_close",
-								"bh_double_quote_content",
-								"bh_regex",
-								"bh_regex_center",
-								"bh_regex_open",
-								"bh_regex_close",
-								"bh_regex_content",
-								"bh_c_define",
-								"bh_c_define_center",
-								"bh_c_define_open",
-								"bh_c_define_close",
-								"bh_c_define_content",
-								"bh_curly",
-								"bh_curly_center",
-								"bh_curly_open",
-								"bh_curly_close",
-								"bh_curly_content",
-								"bh_angle",
-								"bh_angle_center",
-								"bh_angle_open",
-								"bh_angle_close",
-								"bh_angle_content",
-								"bh_unmatched",
-								"bh_unmatched_center",
-								"bh_unmatched_open",
-								"bh_unmatched_close",
-								"bh_unmatched_content"
-							],
-							"incomplete_sync": null,
-							"remote_loading": false,
-							"synced": false,
-							"syntax": "Packages/Ruby/Ruby.sublime-syntax",
-							"tab_size": 2,
-							"translate_tabs_to_spaces": true
-						},
-						"translation.x": 0.0,
-						"translation.y": 0.0,
-						"zoom_level": 1.0
-					},
-					"stack_index": 1,
-					"type": "text"
-				},
-				{
-					"buffer": 1,
-					"semi_transient": false,
-					"settings":
-					{
-						"buffer_size": 0,
-						"regions":
-						{
-						},
-						"selection":
-						[
-							[
-								0,
-								0
-							]
-						],
-						"settings":
-						{
-							"BracketHighlighterBusy": false,
-							"auto_name": "",
-							"bh_regions":
-							[
-								"bh_curly",
-								"bh_curly_center",
-								"bh_curly_open",
-								"bh_curly_close",
-								"bh_curly_content",
-								"bh_tag",
-								"bh_tag_center",
-								"bh_tag_open",
-								"bh_tag_close",
-								"bh_tag_content",
-								"bh_default",
-								"bh_default_center",
-								"bh_default_open",
-								"bh_default_close",
-								"bh_default_content",
-								"bh_single_quote",
-								"bh_single_quote_center",
-								"bh_single_quote_open",
-								"bh_single_quote_close",
-								"bh_single_quote_content",
-								"bh_unmatched",
-								"bh_unmatched_center",
-								"bh_unmatched_open",
-								"bh_unmatched_close",
-								"bh_unmatched_content",
-								"bh_c_define",
-								"bh_c_define_center",
-								"bh_c_define_open",
-								"bh_c_define_close",
-								"bh_c_define_content",
-								"bh_double_quote",
-								"bh_double_quote_center",
-								"bh_double_quote_open",
-								"bh_double_quote_close",
-								"bh_double_quote_content",
-								"bh_angle",
-								"bh_angle_center",
-								"bh_angle_open",
-								"bh_angle_close",
-								"bh_angle_content",
-								"bh_round",
-								"bh_round_center",
-								"bh_round_open",
-								"bh_round_close",
-								"bh_round_content",
-								"bh_square",
-								"bh_square_center",
-								"bh_square_open",
-								"bh_square_close",
-								"bh_square_content",
-								"bh_regex",
-								"bh_regex_center",
-								"bh_regex_open",
-								"bh_regex_close",
-								"bh_regex_content"
-							],
-							"default_dir": "/home/eike/Repositories/fu/ss15/ma/impl",
-							"incomplete_sync": null,
-							"syntax": "Packages/Text/Plain text.tmLanguage"
-						},
-						"translation.x": 0.0,
-						"translation.y": 0.0,
-						"zoom_level": 1.0
-					},
-					"stack_index": 0,
-					"type": "text"
-				}
 			]
 		}
 	],
diff --git a/vipra-cmd/.settings/org.eclipse.jdt.core.prefs b/vipra-cmd/.settings/org.eclipse.jdt.core.prefs
index cf43e3192a4851c9a5dd6821730ed9cf12c24559..78a9b4501f5ec8e63422f8199df3009d010cfbda 100644
--- a/vipra-cmd/.settings/org.eclipse.jdt.core.prefs
+++ b/vipra-cmd/.settings/org.eclipse.jdt.core.prefs
@@ -278,10 +278,10 @@ org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_decla
 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
 org.eclipse.jdt.core.formatter.join_lines_in_comments=true
 org.eclipse.jdt.core.formatter.join_wrapped_lines=true
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
 org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
 org.eclipse.jdt.core.formatter.lineSplit=120
 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
 org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
diff --git a/vipra-cmd/pom.xml b/vipra-cmd/pom.xml
index c237d34b268573ef5adaa509ab6edbe611fe5e40..d07d0776ed5e8cd46ce8e7126ab0940a4710ab6b 100644
--- a/vipra-cmd/pom.xml
+++ b/vipra-cmd/pom.xml
@@ -85,7 +85,7 @@
 		<dependency>
 			<groupId>org.mongodb</groupId>
 			<artifactId>mongodb-driver</artifactId>
-			<version>3.0.4</version>
+			<version>3.2.0</version>
 		</dependency>
 
 		<!-- Testing -->
diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/model/Article.java b/vipra-cmd/src/main/java/de/vipra/cmd/model/Article.java
index 14fe2ea32125b1990127222d5b678f5e41a9d34a..a29161db1d48d79108ae468ade2823b424aeed17 100644
--- a/vipra-cmd/src/main/java/de/vipra/cmd/model/Article.java
+++ b/vipra-cmd/src/main/java/de/vipra/cmd/model/Article.java
@@ -5,10 +5,14 @@ import org.json.simple.JSONObject;
 public class Article extends de.vipra.util.model.Article {
 
 	public void fromJSON(JSONObject obj) {
-		if (obj.containsKey("title")) setTitle(obj.get("title").toString());
-		if (obj.containsKey("text")) setText(obj.get("text").toString());
-		if (obj.containsKey("url")) setUrl(obj.get("url").toString());
-		if (obj.containsKey("date")) setDate(obj.get("date").toString());
+		if (obj.containsKey("title"))
+			setTitle(obj.get("title").toString());
+		if (obj.containsKey("text"))
+			setText(obj.get("text").toString());
+		if (obj.containsKey("url"))
+			setUrl(obj.get("url").toString());
+		if (obj.containsKey("date"))
+			setDate(obj.get("date").toString());
 	}
 
 }
diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java
index 36fcf9c7833542f442158b18aae857c9c57efb75..d31a756329b1cf8be736e8e5cc4d1290d9f14234 100644
--- a/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java
+++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportCommand.java
@@ -50,6 +50,7 @@ public class ImportCommand implements Command {
 	}
 
 	public static final Logger log = LoggerFactory.getLogger(ImportCommand.class);
+	public static final Logger out = LoggerFactory.getLogger("shellout");
 
 	private ArrayList<File> files = new ArrayList<>();
 	private JSONParser parser = new JSONParser();
@@ -126,7 +127,7 @@ public class ImportCommand implements Command {
 	}
 
 	void importArticle(JSONObject obj) throws ImportException {
-		log.info("importing \"" + StringUtils.ellipsize(obj.get("title").toString(), 80) + "\"");
+		out.info("importing \"" + StringUtils.ellipsize(obj.get("title").toString(), 80) + "\"");
 		Article article = new Article();
 		article.fromJSON(obj);
 
diff --git a/vipra-cmd/src/main/resources/log4j2.xml b/vipra-cmd/src/main/resources/log4j2.xml
index 3a6e439cfe369cd7f57487d0da5f1239f1a9ed91..c28b8da1deb9d9c4c53d81fdb830230a3a86fe8b 100644
--- a/vipra-cmd/src/main/resources/log4j2.xml
+++ b/vipra-cmd/src/main/resources/log4j2.xml
@@ -10,6 +10,5 @@
 			<AppenderRef ref="Console" />
 		</Root>
 		<Logger name="shellout" level="ALL"/>
-		<Logger name="org.mongodb" level="ERROR"/>
 	</Loggers>
 </Configuration>
\ No newline at end of file
diff --git a/vipra-rest/pom.xml b/vipra-rest/pom.xml
index a7b384aa66170c7f9ddcba6c7dadd4da23cb12af..0f1fc40d353bcd82ddc2d52b79d11018f5433156 100644
--- a/vipra-rest/pom.xml
+++ b/vipra-rest/pom.xml
@@ -83,7 +83,7 @@
 		<dependency>
 			<groupId>org.mongodb</groupId>
 			<artifactId>mongodb-driver</artifactId>
-			<version>3.0.4</version>
+			<version>3.2.0</version>
 		</dependency>
 
 		<!-- Testing -->
diff --git a/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java b/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java
index 4c8231addf429dd7898ddd8f561fff862c127e5b..b748acc0cbc1dc60921593b937a78c20508f02a3 100644
--- a/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java
+++ b/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java
@@ -16,6 +16,7 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
 import de.vipra.rest.model.Article;
 import de.vipra.rest.serializer.ArticleDeserializer;
 import de.vipra.rest.serializer.ArticleSerializer;
+import de.vipra.util.Constants;
 
 @Provider
 public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
@@ -41,7 +42,7 @@ public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
 		final ObjectMapper mapper = new ObjectMapper();
 		mapper.enable(SerializationFeature.INDENT_OUTPUT);
 		mapper.setSerializationInclusion(Include.NON_NULL);
-		mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
+		mapper.setDateFormat(new SimpleDateFormat(Constants.DATETIME_FORMAT));
 		mapper.registerModule(module);
 		return mapper;
 	}
diff --git a/vipra-rest/src/main/java/de/vipra/rest/serializer/JsonHelper.java b/vipra-rest/src/main/java/de/vipra/rest/serializer/JsonHelper.java
index 10bfca3a60b0e2f7f716515519407f76cf96f96c..a15ff8ae64aca885be54c03ba35879b04a2ea42b 100644
--- a/vipra-rest/src/main/java/de/vipra/rest/serializer/JsonHelper.java
+++ b/vipra-rest/src/main/java/de/vipra/rest/serializer/JsonHelper.java
@@ -7,6 +7,8 @@ import java.util.Date;
 
 import com.fasterxml.jackson.databind.JsonNode;
 
+import de.vipra.util.Constants;
+
 public class JsonHelper {
 
 	public static <T> T get(JsonNode node, String name, T defaultValue, Class<T> type) {
@@ -45,12 +47,12 @@ public class JsonHelper {
 	}
 
 	public static String dateToString(Date date) {
-		DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+		DateFormat df = new SimpleDateFormat(Constants.DATETIME_FORMAT);
 		return df.format(date);
 	}
 
 	public static Date stringToDate(String source) {
-		DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+		DateFormat df = new SimpleDateFormat(Constants.DATETIME_FORMAT);
 		try {
 			return df.parse(source);
 		} catch (ParseException e) {
diff --git a/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java b/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java
index 3ed4a6156115f122807918d846e7fda5774de6a2..139413e1dbb225cd9ee59f01ae01052a1921fde9 100644
--- a/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java
+++ b/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java
@@ -26,7 +26,9 @@ public class ArticleService extends DatabaseService<Article> {
 	public ArrayList<Article> getArticles(URI base, int skip, int limit, String sortBy) {
 		ArrayList<Article> articles = super.getMultiple(skip, limit, sortBy);
 		for (Article article : articles) {
+			// delete data for listing
 			article.setText(null);
+			article.setStats(null);
 			article.setBase(base);
 		}
 		return articles;
diff --git a/vipra-util/.settings/org.eclipse.jdt.core.prefs b/vipra-util/.settings/org.eclipse.jdt.core.prefs
index 57fd9ccb7a5acf365ce1fead974419e24de10b66..0e1f9aa3cc628583e32a023c1e33ee9a6003f133 100644
--- a/vipra-util/.settings/org.eclipse.jdt.core.prefs
+++ b/vipra-util/.settings/org.eclipse.jdt.core.prefs
@@ -277,10 +277,10 @@ org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_decla
 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
 org.eclipse.jdt.core.formatter.join_lines_in_comments=true
 org.eclipse.jdt.core.formatter.join_wrapped_lines=true
-org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
 org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
-org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
-org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
 org.eclipse.jdt.core.formatter.lineSplit=120
 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
 org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
diff --git a/vipra-util/pom.xml b/vipra-util/pom.xml
index 59d8436d1af0eb92ddd79512ee90221ea4b66d8b..f0bfa6d77d5be229a604bed02466d57b87f509af 100644
--- a/vipra-util/pom.xml
+++ b/vipra-util/pom.xml
@@ -41,7 +41,7 @@
 		<dependency>
 			<groupId>org.mongodb</groupId>
 			<artifactId>mongodb-driver</artifactId>
-			<version>3.0.4</version>
+			<version>3.2.0</version>
 		</dependency>
 
 		<!-- ElasticSearch Adapter -->
diff --git a/vipra-util/src/main/java/de/vipra/util/Constants.java b/vipra-util/src/main/java/de/vipra/util/Constants.java
index 4aa09bf529ea532180df0bdcd4d4b8fb31a73a01..0655844e35d857cf2a5ca6d280dae7956253cb50 100644
--- a/vipra-util/src/main/java/de/vipra/util/Constants.java
+++ b/vipra-util/src/main/java/de/vipra/util/Constants.java
@@ -14,6 +14,8 @@ public class Constants {
 	public static final String DEFAULT_HOST = "localhost";
 	public static final int DEFAULT_PORT = 27017;
 	public static final String DEFAULT_DB = "test";
+	
+	public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
 
 	public static enum Collection {
 		ARTICLES("articles");
diff --git a/vipra-util/src/main/java/de/vipra/util/model/Article.java b/vipra-util/src/main/java/de/vipra/util/model/Article.java
index a121c216665b4f46e17992fc6595af3ac42f0092..8d1490166e3d5b1cebf70aa16f3f7a76935db726 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/Article.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/Article.java
@@ -8,9 +8,10 @@ import java.util.Date;
 import java.util.List;
 
 import org.bson.Document;
-import org.bson.types.ObjectId;
 
+import de.vipra.util.Constants;
 import de.vipra.util.FileUtils;
+import de.vipra.util.MongoUtils;
 import de.vipra.util.StringUtils;
 
 public class Article extends Model {
@@ -71,7 +72,7 @@ public class Article extends Model {
 	}
 
 	public void setDate(String date) {
-		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+		SimpleDateFormat df = new SimpleDateFormat(Constants.DATETIME_FORMAT);
 		try {
 			setDate(df.parse(date));
 		} catch (ParseException e) {}
@@ -84,11 +85,16 @@ public class Article extends Model {
 
 	@Override
 	public Document toDocument() {
-		Document doc = new Document("title", title).append("text", text).append("url", url).append("date", date);
-		if (getId() != null) {
-			doc.append("_id", new ObjectId(getId()));
-		}
-		return doc;
+		Document document = new Document();
+		if (getId() != null)
+			document.put("_id", MongoUtils.objectId(getId()));
+		document.put("title", getTitle());
+		document.put("text", getText());
+		document.put("url", getUrl());
+		document.put("date", getDate());
+		if (getStats() != null)
+			document.put("stats", getStats().toDocument());
+		return document;
 	}
 
 	@Override
@@ -98,6 +104,8 @@ public class Article extends Model {
 		setText(document.getString("text"));
 		setUrl(document.getString("url"));
 		setDate(document.getDate("date"));
+		if (document.containsKey("stats"))
+			setStats(new ArticleStats((Document) document.get("stats")));
 	}
 
 	@Override
diff --git a/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java b/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java
index dc06372ec9d12b7ce6a97fbcf0eeec4cf6b8deeb..2b4cc36c6b3c7ca1381e5b2d3d93effbd25d743f 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/ArticleStats.java
@@ -3,12 +3,20 @@ package de.vipra.util.model;
 import java.util.HashMap;
 import java.util.Map;
 
-public class ArticleStats {
+import org.bson.Document;
+
+public class ArticleStats implements BsonDocument {
 
 	private long wordCount;
 	private long uniqueWordCount;
 	private Map<String, TermFrequency> uniqueWords;
 
+	public ArticleStats() {}
+
+	public ArticleStats(Document document) {
+		fromDocument(document);
+	}
+
 	public long getWordCount() {
 		return wordCount;
 	}
@@ -61,4 +69,33 @@ public class ArticleStats {
 		return stats;
 	}
 
+	@Override
+	public Document toDocument() {
+		Document document = new Document();
+		document.put("wordCount", getWordCount());
+		document.put("uniqueWordCount", getUniqueWordCount());
+		if (getUniqueWords() != null) {
+			Document uniqueWords = new Document();
+			for (Map.Entry<String, TermFrequency> entry : getUniqueWords().entrySet()) {
+				uniqueWords.put(entry.getKey(), entry.getValue().toDocument());
+			}
+			document.put("uniqueWords", uniqueWords);
+		}
+		return document;
+	}
+
+	@Override
+	public void fromDocument(Document document) {
+		setWordCount(document.getLong("wordCount"));
+		setUniqueWordCount(document.getLong("uniqueWordCount"));
+		if (document.containsKey("uniqueWords")) {
+			Map<String, TermFrequency> uniqueWords = new HashMap<>();
+			Document docUniqueWords = (Document) document.get("uniqueWords");
+			for (Map.Entry<String, Object> entry : docUniqueWords.entrySet()) {
+				uniqueWords.put(entry.getKey(), new TermFrequency((Document) entry.getValue()));
+			}
+			setUniqueWords(uniqueWords);
+		}
+	}
+
 }
diff --git a/vipra-util/src/main/java/de/vipra/util/model/BsonDocument.java b/vipra-util/src/main/java/de/vipra/util/model/BsonDocument.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a606205b442c1df26e2551c5ce37fc06004a68f
--- /dev/null
+++ b/vipra-util/src/main/java/de/vipra/util/model/BsonDocument.java
@@ -0,0 +1,11 @@
+package de.vipra.util.model;
+
+import org.bson.Document;
+
+public interface BsonDocument {
+
+	Document toDocument();
+
+	void fromDocument(Document document);
+
+}
diff --git a/vipra-util/src/main/java/de/vipra/util/model/Model.java b/vipra-util/src/main/java/de/vipra/util/model/Model.java
index 264b7ab6e3cc52cc5ad805cd730d63c411f184bb..db4f5ec17c2de516d7a1ec83858a052be620ffe2 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/Model.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/Model.java
@@ -10,7 +10,7 @@ import org.bson.Document;
 
 import de.vipra.util.Constants;
 
-public abstract class Model {
+public abstract class Model implements BsonDocument {
 
 	private String id;
 
diff --git a/vipra-util/src/main/java/de/vipra/util/model/TermFrequency.java b/vipra-util/src/main/java/de/vipra/util/model/TermFrequency.java
index 8008d7ece49c33dfb512dd6bae063eb6e7dd19ef..c97fa1e07e12a5d4f293ff1e5f7f564432d68986 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/TermFrequency.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/TermFrequency.java
@@ -1,10 +1,18 @@
 package de.vipra.util.model;
 
-public class TermFrequency {
+import org.bson.Document;
+
+public class TermFrequency implements BsonDocument {
 
 	private long termFrequency = 0;
-	private long normalizedTermFrequency = 0;
-	private long inverseDocumentFrequency = 0;
+	private double normalizedTermFrequency = 0;
+	private double inverseDocumentFrequency = 0;
+
+	public TermFrequency() {}
+
+	public TermFrequency(Document document) {
+		fromDocument(document);
+	}
 
 	public long getTermFrequency() {
 		return termFrequency;
@@ -14,15 +22,15 @@ public class TermFrequency {
 		this.termFrequency = termFrequency;
 	}
 
-	public long getNormalizedTermFrequency() {
+	public double getNormalizedTermFrequency() {
 		return normalizedTermFrequency;
 	}
 
-	public void setNormalizedTermFrequency(long normalizedTermFrequency) {
+	public void setNormalizedTermFrequency(double normalizedTermFrequency) {
 		this.normalizedTermFrequency = normalizedTermFrequency;
 	}
 
-	public void normalizeTermFrequency(long max) {
+	public void normalizeTermFrequency(double max) {
 		setNormalizedTermFrequency(getNormalizedTermFrequency() / max);
 	}
 
@@ -30,12 +38,28 @@ public class TermFrequency {
 		setTermFrequency(getTermFrequency() + 1);
 	}
 
-	public long getInverseDocumentFrequency() {
+	public double getInverseDocumentFrequency() {
 		return inverseDocumentFrequency;
 	}
 
-	public void setInverseDocumentFrequency(long inverseDocumentFrequency) {
+	public void setInverseDocumentFrequency(double inverseDocumentFrequency) {
 		this.inverseDocumentFrequency = inverseDocumentFrequency;
 	}
 
+	@Override
+	public Document toDocument() {
+		Document document = new Document();
+		document.put("tf", getTermFrequency());
+		document.put("ntf", getNormalizedTermFrequency());
+		document.put("idf", getInverseDocumentFrequency());
+		return document;
+	}
+
+	@Override
+	public void fromDocument(Document document) {
+		setTermFrequency(document.getLong("tf"));
+		setNormalizedTermFrequency(document.getDouble("ntf"));
+		setInverseDocumentFrequency(document.getDouble("idf"));
+	}
+
 }