Fixed serialization (breaks a lot of stuff though)
diff --git a/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java b/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java
index a6379ec..7a4e40b 100644
--- a/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java
+++ b/src/main/java/de/ids_mannheim/korap/index/FieldDocument.java
@@ -41,405 +41,405 @@
     private FieldType keywords  = new FieldType(TextField.TYPE_STORED);
 
     {
-	tvField.setStoreTermVectors(true);
-	tvField.setStoreTermVectorPositions(true);
-	tvField.setStoreTermVectorPayloads(true);
-	tvField.setStoreTermVectorOffsets(false);
+        tvField.setStoreTermVectors(true);
+        tvField.setStoreTermVectorPositions(true);
+        tvField.setStoreTermVectorPayloads(true);
+        tvField.setStoreTermVectorOffsets(false);
 
-	tvNoField.setStoreTermVectors(true);
-	tvNoField.setStoreTermVectorPositions(true);
-	tvNoField.setStoreTermVectorPayloads(true);
-	tvNoField.setStoreTermVectorOffsets(false);
+        tvNoField.setStoreTermVectors(true);
+        tvNoField.setStoreTermVectorPositions(true);
+        tvNoField.setStoreTermVectorPayloads(true);
+        tvNoField.setStoreTermVectorOffsets(false);
 
-	keywords.setStoreTermVectors(true);
-	keywords.setStoreTermVectorPositions(false);
-	keywords.setStoreTermVectorPayloads(false);
-	keywords.setStoreTermVectorOffsets(false);
-	keywords.setIndexOptions(IndexOptions.DOCS_ONLY);
-    }
+        keywords.setStoreTermVectors(true);
+        keywords.setStoreTermVectorPositions(false);
+        keywords.setStoreTermVectorPayloads(false);
+        keywords.setStoreTermVectorOffsets(false);
+        keywords.setIndexOptions(IndexOptions.DOCS_ONLY);
+    };
 
     // see http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html
 
     public void addInt (String key, int value) {
-	doc.add(new IntField(key, value, Field.Store.YES));
+        doc.add(new IntField(key, value, Field.Store.YES));
     };
 
     public void addInt (String key, String value) {
-	this.addInt(key, Integer.parseInt(value));
+        this.addInt(key, Integer.parseInt(value));
     };
 
     public void addText (String key, String value) {
-	doc.add(new TextField(key, value, Field.Store.YES));
+        doc.add(new TextField(key, value, Field.Store.YES));
     };
 
     public void addKeyword (String key, String value) {
-	doc.add(new Field(key, value, keywords));
+        doc.add(new Field(key, value, keywords));
     };
 
     public void addString (String key, String value) {
-	doc.add(new StringField(key, value, Field.Store.YES));
+        doc.add(new StringField(key, value, Field.Store.YES));
     };
 
     public void addStored (String key, String value) {
-	doc.add(new StoredField(key, value));
+        doc.add(new StoredField(key, value));
     };
 
     public void addStored (String key, int value) {
-	doc.add(new StoredField(key, value));
+        doc.add(new StoredField(key, value));
     };
 
     public void addTV (String key, String value, String tsString) {
-	this.addTV(key, value, new MultiTermTokenStream(tsString));
+        this.addTV(key, value, new MultiTermTokenStream(tsString));
     };
 
     public void addTV (String key, String tsString) {
-	this.addTV(key, new MultiTermTokenStream(tsString));
+        this.addTV(key, new MultiTermTokenStream(tsString));
     };
 
     public void addTV (String key, String value, MultiTermTokenStream ts) {
-	Field textField = new Field( key, value, tvField );
-	textField.setTokenStream( ts );
-	doc.add(textField);
+        Field textField = new Field( key, value, tvField );
+        textField.setTokenStream( ts );
+        doc.add(textField);
     };
 
     public void addTV (String key, MultiTermTokenStream ts) {
-	Field textField = new Field( key, ts, tvNoField );
-	doc.add(textField);
+        Field textField = new Field( key, ts, tvNoField );
+        doc.add(textField);
     };
 
     public String toString () {
-	return doc.toString();
+        return doc.toString();
     };
 
     public MultiTermTokenStream newMultiTermTokenStream (String ts) {
-	return new MultiTermTokenStream(ts);
+        return new MultiTermTokenStream(ts);
     };
 
     public MultiTermTokenStream newMultiTermTokenStream () {
-	return new MultiTermTokenStream();
+        return new MultiTermTokenStream();
     };
 
     /**
      * Deserialize token stream data.
      */
     public void setData (Map<String,Object> node) {
-	this.setPrimaryData((String) node.get("text"));
+        this.setPrimaryData((String) node.get("text"));
 
-	String fieldName = (String) node.get("name");
-	MultiTermTokenStream mtts = this.newMultiTermTokenStream();
+        String fieldName = (String) node.get("name");
+        MultiTermTokenStream mtts = this.newMultiTermTokenStream();
 
-	// Iterate over all tokens in stream
-	for (ArrayList<String> token : (ArrayList<ArrayList<String>>) node.get("stream")) {
+        // Iterate over all tokens in stream
+        for (ArrayList<String> token : (ArrayList<ArrayList<String>>) node.get("stream")) {
 
-	    // Initialize MultiTermToken
-	    MultiTermToken mtt = new MultiTermToken(token.remove(0));
+            // Initialize MultiTermToken
+            MultiTermToken mtt = new MultiTermToken(token.remove(0));
 
-	    // Add rest of the list
-	    for (String term : token)
-		mtt.add(term);
+            // Add rest of the list
+            for (String term : token)
+                mtt.add(term);
 
-	    // Add MultiTermToken to stream
-	    mtts.addMultiTermToken(mtt);
-	};
+            // Add MultiTermToken to stream
+            mtts.addMultiTermToken(mtt);
+        };
 
-	// Add tokenstream to fielddocument
-	this.addTV(fieldName, this.getPrimaryData(), mtts);
+        // Add tokenstream to fielddocument
+        this.addTV(fieldName, this.getPrimaryData(), mtts);
 
-	// Get foundry info
-	if (node.containsKey("foundries"))
-	    this.setFoundries((String) node.get("foundries"));
+        // Get foundry info
+        if (node.containsKey("foundries"))
+            this.setFoundries((String) node.get("foundries"));
 
-	// Get layer info
-	if (node.containsKey("layerInfos"))
-	    this.setLayerInfos((String) node.get("layerInfos"));
+        // Get layer info
+        if (node.containsKey("layerInfos"))
+            this.setLayerInfos((String) node.get("layerInfos"));
 
-	// Get tokenSource info
-	if (node.containsKey("tokenSource"))
-	    this.setTokenSource((String) node.get("tokenSource"));
+        // Get tokenSource info
+        if (node.containsKey("tokenSource"))
+            this.setTokenSource((String) node.get("tokenSource"));
     };
 
     /**
      * Deserialize token stream data (LEGACY).
      */
     public void setFields (ArrayList<Map<String,Object>> fields) {
+        
+        Map<String,Object> primary = fields.remove(0);
+        this.setPrimaryData((String) primary.get("primaryData"));
 
-	Map<String,Object> primary = fields.remove(0);
-	this.setPrimaryData((String) primary.get("primaryData"));
+        for (Map<String,Object> field : fields) {
 
-	for (Map<String,Object> field : fields) {
+            String fieldName = (String) field.get("name");
+            MultiTermTokenStream mtts = this.newMultiTermTokenStream();
 
-	    String fieldName = (String) field.get("name");
-	    MultiTermTokenStream mtts = this.newMultiTermTokenStream();
+            for (ArrayList<String> token : (ArrayList<ArrayList<String>>) field.get("data")) {
 
-	    for (ArrayList<String> token : (ArrayList<ArrayList<String>>) field.get("data")) {
+                MultiTermToken mtt = new MultiTermToken(token.remove(0));
 
-		MultiTermToken mtt = new MultiTermToken(token.remove(0));
+                for (String term : token) {
+                    mtt.add(term);
+                };
 
-		for (String term : token) {
-		    mtt.add(term);
-		};
+                mtts.addMultiTermToken(mtt);
+            };
 
-		mtts.addMultiTermToken(mtt);
-	    };
+            // TODO: This is normally dependend to the tokenization!
+            //       Add this as meta information to the document
+            // Store this information as well as tokenization information
+            // as meta fields in the tokenization term vector
+            if (field.containsKey("foundries")) {
+                // TODO: Do not store positions!
+                String foundries = (String) field.get("foundries");
+                this.addKeyword("foundries", foundries);
+                super.setFoundries(foundries);
+            };
+            if (field.containsKey("tokenization")) {
+                String tokenization = (String) field.get("tokenization");
+                this.addString("tokenization", tokenization);
+                super.setTokenization(tokenization);
+            };
 
-	    // TODO: This is normally dependend to the tokenization!
-	    //       Add this as meta information to the document
-	    // Store this information as well as tokenization information
-	    // as meta fields in the tokenization term vector
-	    if (field.containsKey("foundries")) {
-		// TODO: Do not store positions!
-		String foundries = (String) field.get("foundries");
-		this.addKeyword("foundries", foundries);
-		super.setFoundries(foundries);
-	    };
-	    if (field.containsKey("tokenization")) {
-		String tokenization = (String) field.get("tokenization");
-		this.addString("tokenization", tokenization);
-		super.setTokenization(tokenization);
-	    };
-
-	    this.addTV(fieldName, this.getPrimaryData(), mtts);
-	};
+            this.addTV(fieldName, this.getPrimaryData(), mtts);
+        };
     };
 
     @Override
     public void setTextClass (String textClass) {
-	super.setTextClass(textClass);
-	this.addKeyword("textClass", textClass);
+        super.setTextClass(textClass);
+        this.addKeyword("textClass", textClass);
     };
 
     @Override
     public void setTitle (String title) {
-	super.setTitle(title);
-	this.addText("title", title);
+        super.setTitle(title);
+        this.addText("title", title);
     };
 
     @Override
     public void setSubTitle (String subTitle) {
-	super.setSubTitle(subTitle);
-	this.addText("subTitle", subTitle);
+        super.setSubTitle(subTitle);
+        this.addText("subTitle", subTitle);
     };
 
     @Override
     public void setAuthor (String author) {
-	super.setAuthor(author);
-	this.addText("author", author);
+        super.setAuthor(author);
+        this.addText("author", author);
     };
 
     @Override
     public void setPubPlace (String pubPlace) {
-	super.setPubPlace(pubPlace);
-	this.addString("pubPlace", pubPlace);
+        super.setPubPlace(pubPlace);
+        this.addString("pubPlace", pubPlace);
     };
 
     @JsonProperty("pubDate")
     @Override
     public KorapDate setPubDate (String pubDate) {
-	KorapDate date = super.setPubDate(pubDate);
-	this.addInt("pubDate", date.toString());
-	return date;
+        KorapDate date = super.setPubDate(pubDate);
+        this.addInt("pubDate", date.toString());
+        return date;
     };
 
     @JsonProperty("creationDate")
     @Override
     public KorapDate setCreationDate (String creationDate) {
-	KorapDate date = super.setCreationDate(creationDate);
-	this.addInt("creationDate", date.toString());
-	return date;
+        KorapDate date = super.setCreationDate(creationDate);
+        this.addInt("creationDate", date.toString());
+        return date;
     };
 
     // No longer supported
     @Override
     public void setCorpusID (String corpusID) {
-	super.setCorpusID(corpusID);
-	this.addString("corpusID", corpusID);
+        super.setCorpusID(corpusID);
+        this.addString("corpusID", corpusID);
     };
 
     // No longer supported
     @Override
     public void setID (String ID) {
-	super.setID(ID);
-	this.addString("ID", ID);
+        super.setID(ID);
+        this.addString("ID", ID);
     };
 
     @Override
     public void setUID (int ID) {
-	super.setUID(ID);
-	this.addString("UID", new Integer(ID).toString());
+        super.setUID(ID);
+        this.addString("UID", new Integer(ID).toString());
     };
 
     // No longer supported
     @Override
     public void setLayerInfo (String layerInfo) {
-	super.setLayerInfo(layerInfo);
-	this.addStored("layerInfo", layerInfo);
+        super.setLayerInfo(layerInfo);
+        this.addStored("layerInfo", layerInfo);
     };
 
     @Override
     public void setLayerInfos (String layerInfos) {
-	super.setLayerInfos(layerInfos);
-	this.addStored("layerInfos", layerInfos);
+        super.setLayerInfos(layerInfos);
+        this.addStored("layerInfos", layerInfos);
     };
 
     @Override
     public void setTextSigle (String textSigle) {
-	super.setTextSigle(textSigle);
-	this.addString("textSigle", textSigle);
+        super.setTextSigle(textSigle);
+        this.addString("textSigle", textSigle);
     };
 
     @Override
     public void setDocSigle (String docSigle) {
-	super.setDocSigle(docSigle);
-	this.addString("docSigle", docSigle);
+        super.setDocSigle(docSigle);
+        this.addString("docSigle", docSigle);
     };
 
     @Override
     public void setCorpusSigle (String corpusSigle) {
-	super.setCorpusSigle(corpusSigle);
-	this.addString("corpusSigle", corpusSigle);
+        super.setCorpusSigle(corpusSigle);
+        this.addString("corpusSigle", corpusSigle);
     };
 
     @Override
     public void setPublisher (String publisher) {
-	super.setPublisher(publisher);
-	this.addStored("publisher", publisher);
+        super.setPublisher(publisher);
+        this.addStored("publisher", publisher);
     };
 
     @Override
     public void setEditor (String editor) {
-	super.setEditor(editor);
-	this.addStored("editor", editor);
+        super.setEditor(editor);
+        this.addStored("editor", editor);
     };
 
     @Override
     public void setTextType (String textType) {
-	super.setTextType(textType);
-	this.addString("textType", textType);
+        super.setTextType(textType);
+        this.addString("textType", textType);
     };
 
     @Override
     public void setTextTypeArt (String textTypeArt) {
-	super.setTextTypeArt(textTypeArt);
-	this.addString("textTypeArt", textTypeArt);
+        super.setTextTypeArt(textTypeArt);
+        this.addString("textTypeArt", textTypeArt);
     };
 
     @Override
     public void setTextTypeRef (String textTypeRef) {
-	super.setTextTypeRef(textTypeRef);
-	this.addString("textTypeRef", textTypeRef);
+        super.setTextTypeRef(textTypeRef);
+        this.addString("textTypeRef", textTypeRef);
     };
 
     @Override
     public void setTextColumn (String textColumn) {
-	super.setTextColumn(textColumn);
-	this.addString("textColumn", textColumn);
+        super.setTextColumn(textColumn);
+        this.addString("textColumn", textColumn);
     };
 
     @Override
     public void setTextDomain (String textDomain) {
-	super.setTextDomain(textDomain);
-	this.addString("textDomain", textDomain);
+        super.setTextDomain(textDomain);
+        this.addString("textDomain", textDomain);
     };
 
     @Override
     public void setLicense (String license) {
-	super.setLicense(license);
-	this.addString("license", license);
+        super.setLicense(license);
+        this.addString("license", license);
     };
 
     @Override
     public void setPages (String pages) {
-	super.setPages(pages);
-	this.addStored("pages", pages);
+        super.setPages(pages);
+        this.addStored("pages", pages);
     };
 
     @Override
     public void setFileEditionStatement (String fileEditionStatement) {
-	super.setFileEditionStatement(fileEditionStatement);
-	this.addStored("fileEditionStatement", fileEditionStatement);
+        super.setFileEditionStatement(fileEditionStatement);
+        this.addStored("fileEditionStatement", fileEditionStatement);
     };
 
     @Override
     public void setBiblEditionStatement (String biblEditionStatement) {
-	super.setBiblEditionStatement(biblEditionStatement);
-	this.addStored("biblEditionStatement", biblEditionStatement);
+        super.setBiblEditionStatement(biblEditionStatement);
+        this.addStored("biblEditionStatement", biblEditionStatement);
     };
 
     @Override
     public void setReference (String reference) {
-	super.setReference(reference);
-	this.addStored("reference", reference);
+        super.setReference(reference);
+        this.addStored("reference", reference);
     };
 
     @Override
     public void setLanguage (String language) {
-	super.setLanguage(language);
-	this.addString("language", language);
+        super.setLanguage(language);
+        this.addString("language", language);
     };
 
     @Override
     public void setDocTitle (String docTitle) {
-	super.setDocTitle(docTitle);
-	this.addText("docTitle", docTitle);
+        super.setDocTitle(docTitle);
+        this.addText("docTitle", docTitle);
     };
 
     @Override
     public void setDocSubTitle (String docSubTitle) {
-	super.setDocSubTitle(docSubTitle);
-	this.addText("docSubTitle", docSubTitle);
+        super.setDocSubTitle(docSubTitle);
+        this.addText("docSubTitle", docSubTitle);
     };
 
     @Override
     public void setDocAuthor (String docAuthor) {
-	super.setDocAuthor(docAuthor);
-	this.addText("docAuthor", docAuthor);
+        super.setDocAuthor(docAuthor);
+        this.addText("docAuthor", docAuthor);
     };
 
     @Override
     public void setDocEditor (String docEditor) {
-	super.setDocEditor(docEditor);
-	this.addStored("docEditor", docEditor);
+        super.setDocEditor(docEditor);
+        this.addStored("docEditor", docEditor);
     };
 
     @Override
     public void setCorpusTitle (String corpusTitle) {
-	super.setCorpusTitle(corpusTitle);
-	this.addText("corpusTitle", corpusTitle);
+        super.setCorpusTitle(corpusTitle);
+        this.addText("corpusTitle", corpusTitle);
     };
 
     @Override
     public void setCorpusSubTitle (String corpusSubTitle) {
-	super.setCorpusSubTitle(corpusSubTitle);
-	this.addText("corpusSubTitle", corpusSubTitle);
+        super.setCorpusSubTitle(corpusSubTitle);
+        this.addText("corpusSubTitle", corpusSubTitle);
     };
 
     @Override
     public void setCorpusAuthor (String corpusAuthor) {
-	super.setCorpusAuthor(corpusAuthor);
-	this.addText("corpusAuthor", corpusAuthor);
+        super.setCorpusAuthor(corpusAuthor);
+        this.addText("corpusAuthor", corpusAuthor);
     };
 
     @Override
     public void setCorpusEditor (String corpusEditor) {
-	super.setCorpusEditor(corpusEditor);
-	this.addStored("corpusEditor", corpusEditor);
+        super.setCorpusEditor(corpusEditor);
+        this.addStored("corpusEditor", corpusEditor);
     };
 
     @Override
     public void setKeywords (String keywords) {
-	super.setKeywords(keywords);
-	this.addKeyword("keywords", keywords);
+        super.setKeywords(keywords);
+        this.addKeyword("keywords", keywords);
     };
 
     @Override
     public void setTokenSource (String tokenSource) {
-	super.setTokenSource(tokenSource);
-	this.addStored("tokenSource", tokenSource);
+        super.setTokenSource(tokenSource);
+        this.addStored("tokenSource", tokenSource);
     };
 
     @Override
     public void setFoundries (String foundries) {
-	super.setFoundries(foundries);
-	this.addKeyword("foundries", foundries);
+        super.setFoundries(foundries);
+        this.addKeyword("foundries", foundries);
     };
 };
diff --git a/src/main/java/de/ids_mannheim/korap/response/KorapResponse.java b/src/main/java/de/ids_mannheim/korap/response/KorapResponse.java
index 46d4028..c826f71 100644
--- a/src/main/java/de/ids_mannheim/korap/response/KorapResponse.java
+++ b/src/main/java/de/ids_mannheim/korap/response/KorapResponse.java
@@ -7,7 +7,10 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
 import de.ids_mannheim.korap.response.Notifications;
+import de.ids_mannheim.korap.response.serialize.KorapResponseDeserializer;
 
 /**
  * Base class for objects meant to be responded by the server.
@@ -23,6 +26,7 @@
  * @author Nils Diewald
  * @see de.ids_mannheim.korap.response.Notifications
  */
+@JsonDeserialize(using = KorapResponseDeserializer.class)
 public class KorapResponse extends Notifications {
     ObjectMapper mapper = new ObjectMapper();
 
@@ -30,7 +34,6 @@
     private String benchmark;
     private boolean timeExceeded = false;
 
-
     /**
      * Construct a new KorapResponse object.
      *
@@ -47,8 +50,8 @@
      */
     @JsonIgnore
     public KorapResponse setVersion (String version) {
-	this.version = version;
-	return this;
+        this.version = version;
+        return this;
     };
 
 
@@ -59,7 +62,7 @@
      */
     @JsonIgnore
     public String getVersion () {
-	return this.version;
+        return this.version;
     };
 
 
@@ -72,8 +75,8 @@
      */
     @JsonIgnore
     public KorapResponse setName (String name) {
-	this.name = name;
-	return this;
+        this.name = name;
+        return this;
     };
 
 
@@ -85,7 +88,7 @@
      */
     @JsonIgnore
     public String getName () {
-	return this.name;
+        return this.name;
     };
 
 
@@ -98,8 +101,8 @@
      */
     @JsonIgnore
     public KorapResponse setNode (String name) {
-	this.node = name;
-	return this;
+        this.node = name;
+        return this;
     };
 
 
@@ -111,9 +114,9 @@
      */
     @JsonIgnore
     public String getNode () {
-	return this.node;
+        return this.node;
     };
-
+    
 
     /**
      * Set to <tt>true</tt> if time is exceeded
@@ -128,10 +131,10 @@
      */
     @JsonIgnore
     public KorapResponse setTimeExceeded (boolean timeout) {
-	if (timeout)
-	    this.addWarning(682, "Response time exceeded");
-	this.timeExceeded = timeout;
-	return this;
+        if (timeout)
+            this.addWarning(682, "Response time exceeded");
+        this.timeExceeded = timeout;
+        return this;
     };
 
 
@@ -142,8 +145,8 @@
      *         otherwise <tt>false</tt>
      */
     @JsonIgnore
-    public boolean getTimeExceeded () {
-	return this.timeExceeded;
+    public boolean hasTimeExceeded () {
+        return this.timeExceeded;
     };
 
 
@@ -157,14 +160,14 @@
     @JsonIgnore
     public KorapResponse setBenchmark (long ts1, long ts2) {
         this.benchmark =
-	    (ts2 - ts1) < 100_000_000 ?
-	    // Store as miliseconds
-	    (((double) (ts2 - ts1) * 1e-6) + " ms") :
-	    // Store as seconds
-	    (((double) (ts2 - ts1) / 1000000000.0) + " s");
-	return this;
+            (ts2 - ts1) < 100_000_000 ?
+            // Store as miliseconds
+            (((double) (ts2 - ts1) * 1e-6) + " ms") :
+            // Store as seconds
+            (((double) (ts2 - ts1) / 1000000000.0) + " s");
+        return this;
     };
-
+    
 
     /**
      * Set the benchmark as a string representation.
@@ -175,8 +178,8 @@
      */
     @JsonIgnore
     public KorapResponse setBenchmark (String bm) {
-	this.benchmark = bm;
-	return this;
+        this.benchmark = bm;
+        return this;
     };
 
 
@@ -190,7 +193,7 @@
     public String getBenchmark () {
         return this.benchmark;
     };
-
+    
 
     /**
      * Set the listener URI as a String. This is probably the localhost
@@ -206,10 +209,10 @@
      */
     @JsonIgnore
     public KorapResponse setListener (String listener) {
-	this.listener = listener;
-	return this;
+        this.listener = listener;
+        return this;
     };
-
+    
 
     /**
      * Get the listener URI as a string.
@@ -218,7 +221,7 @@
      */
     @JsonIgnore
     public String getListener () {
-	return this.listener;
+        return this.listener;
     };
 
 
@@ -230,27 +233,27 @@
     @Override
     public JsonNode toJsonNode () {
 
-	// Get notifications json response
-	ObjectNode json = (ObjectNode) super.toJsonNode();
+        // Get notifications json response
+        ObjectNode json = (ObjectNode) super.toJsonNode();
 
-	StringBuilder sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder();
         if (this.getName() != null) {
-	    sb.append(this.getName());
+            sb.append(this.getName());
+            
+            if (this.getVersion() != null)
+                sb.append("-");
+        };
 
-	    if (this.getVersion() != null)
-		sb.append("-");
-	};
+        // No name but version is given
+        if (this.getVersion() != null)
+            sb.append(this.getVersion());
 
-	// No name but version is given
-	if (this.getVersion() != null)
-	    sb.append(this.getVersion());
-
-	if (sb.length() > 0)
-	    json.put("version", sb.toString());
-
-	if (this.timeExceeded)
-	    json.put("timeExceeded", true);
-
+        if (sb.length() > 0)
+            json.put("version", sb.toString());
+        
+        if (this.timeExceeded)
+            json.put("timeExceeded", true);
+        
         if (this.getNode() != null)
             json.put("node", this.getNode());
 
@@ -260,7 +263,7 @@
         if (this.getBenchmark() != null)
             json.put("benchmark", this.getBenchmark());
 
-	return (JsonNode) json;
+        return (JsonNode) json;
     };
 
     /**
@@ -286,19 +289,19 @@
      * @return String representation of the response
      */
     public String toJsonString () {
-	String msg = "";
-	try {
-	    return mapper.writeValueAsString(this.toJsonNode());
-	}
-	catch (Exception e) {
-	    // Bad in case the message contains quotes!
-	    msg = ", \"" + e.getLocalizedMessage() + "\"";
-	};
+        String msg = "";
+        try {
+            return mapper.writeValueAsString(this.toJsonNode());
+        }
+        catch (Exception e) {
+            // Bad in case the message contains quotes!
+            msg = ", \"" + e.getLocalizedMessage() + "\"";
+        };
 
-	return
-	    "{\"errors\":["+
-	    "[620, " +
-	    "\"Unable to generate JSON\"" + msg + "]" +
-	    "]}";
+        return
+            "{\"errors\":["+
+            "[620, " +
+            "\"Unable to generate JSON\"" + msg + "]" +
+            "]}";
     };
 };
diff --git a/src/main/java/de/ids_mannheim/korap/response/serialize/KorapResponseDeserializer.java b/src/main/java/de/ids_mannheim/korap/response/serialize/KorapResponseDeserializer.java
new file mode 100644
index 0000000..3e009bd
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/response/serialize/KorapResponseDeserializer.java
@@ -0,0 +1,60 @@
+package de.ids_mannheim.korap.response.serialize;
+
+import java.util.*;
+import java.io.*;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+
+import de.ids_mannheim.korap.response.KorapResponse;
+
+public class KorapResponseDeserializer extends JsonDeserializer<KorapResponse> {
+ 
+    @Override
+    public KorapResponse deserialize (JsonParser parser, DeserializationContext ctxt)
+        throws IOException, JsonProcessingException {
+        JsonNode node = parser.getCodec().readTree(parser);
+        KorapResponse kresp = new KorapResponse();
+
+        // Deserialize version information
+        if (node.has("version")) {
+            String fullVersion = node.get("version").asText();
+            int found = fullVersion.lastIndexOf('-');
+
+            // Is combined name and version
+            if (found > 0 && (found + 1 < fullVersion.length())) {
+                kresp.setName(fullVersion.substring(0, found))
+                     .setVersion(fullVersion.substring(found + 1));
+            }
+            // Is only version number
+            else {
+                kresp.setVersion(fullVersion);
+            };
+        };
+
+        // Deserialize timeout information
+        if (node.has("timeExceeded") && node.get("timeExceeded").asBoolean()) {
+            kresp.setTimeExceeded(true);
+        };
+
+        // Deserialize benchmark information
+        if (node.has("benchmark"))
+            kresp.setBenchmark(node.get("benchmark").asText());
+
+        // Deserialize listener information
+        if (node.has("listener"))
+            kresp.setListener(node.get("listener").asText());
+
+        // Deserialize listener information
+        if (node.has("node"))
+            kresp.setNode(node.get("node").asText());
+
+        // Copy notifications
+        kresp.copyNotificationsFrom(node);
+
+        return kresp;
+    };
+};
diff --git a/src/test/java/de/ids_mannheim/korap/response/TestResponse.java b/src/test/java/de/ids_mannheim/korap/response/TestResponse.java
index b2116cb..43686f0 100644
--- a/src/test/java/de/ids_mannheim/korap/response/TestResponse.java
+++ b/src/test/java/de/ids_mannheim/korap/response/TestResponse.java
@@ -22,63 +22,127 @@
 
     @Test
     public void testResponse () throws IOException {
-	KorapResponse resp = new KorapResponse();
-	assertEquals("{}", resp.toJsonString());
-	resp.setVersion("0.24");
-	resp.setNode("Tanja");
-	assertEquals("0.24",resp.getVersion());
-	assertEquals("Tanja", resp.getNode());
+		KorapResponse resp = new KorapResponse();
+		assertEquals("{}", resp.toJsonString());
+		resp.setVersion("0.24");
+        resp.setNode("Tanja");
+        assertEquals("0.24",resp.getVersion());
+        assertEquals("Tanja", resp.getNode());
 
-	assertFalse(resp.hasWarnings());
-	assertFalse(resp.hasMessages());
-	assertFalse(resp.hasErrors());
+        assertFalse(resp.hasWarnings());
+        assertFalse(resp.hasMessages());
+        assertFalse(resp.hasErrors());
 
-	JsonNode respJson = mapper.readTree(resp.toJsonString());
-	assertEquals("0.24", respJson.at("/version").asText());
-	assertEquals("Tanja", respJson.at("/node").asText());
+        JsonNode respJson = mapper.readTree(resp.toJsonString());
+        assertEquals("0.24", respJson.at("/version").asText());
+        assertEquals("Tanja", respJson.at("/node").asText());
 
-	resp.setName("Index");
-	respJson = mapper.readTree(resp.toJsonString());
-	assertEquals("Index-0.24", respJson.at("/version").asText());
-	assertEquals("Tanja", respJson.at("/node").asText());
+        resp.setName("Index");
+        respJson = mapper.readTree(resp.toJsonString());
+        assertEquals("Index-0.24", respJson.at("/version").asText());
+        assertEquals("Tanja", respJson.at("/node").asText());
 
-	resp.setBenchmark("took a while");
-	resp.setListener("localhost:3000");
-	respJson = mapper.readTree(resp.toJsonString());
-	assertEquals("localhost:3000", respJson.at("/listener").asText());
-	assertEquals("took a while", respJson.at("/benchmark").asText());
+        resp.setBenchmark("took a while");
+        resp.setListener("localhost:3000");
+        respJson = mapper.readTree(resp.toJsonString());
+        assertEquals("localhost:3000", respJson.at("/listener").asText());
+        assertEquals("took a while", respJson.at("/benchmark").asText());
     };
 
     @Test
     public void testResponseNotifications () throws IOException {
-	KorapResponse resp = new KorapResponse();
-	assertEquals("{}", resp.toJsonString());
-	resp.setVersion("0.24");
-	resp.setNode("Tanja");
-	assertEquals("0.24",resp.getVersion());
-	assertEquals("Tanja", resp.getNode());
+        KorapResponse resp = new KorapResponse();
+        assertEquals("{}", resp.toJsonString());
+        resp.setVersion("0.24");
+        resp.setNode("Tanja");
+        assertEquals("0.24",resp.getVersion());
+        assertEquals("Tanja", resp.getNode());
 
-	assertFalse(resp.hasWarnings());
-	assertFalse(resp.hasMessages());
-	assertFalse(resp.hasErrors());
+        assertFalse(resp.hasWarnings());
+        assertFalse(resp.hasMessages());
+        assertFalse(resp.hasErrors());
 
-	JsonNode respJson = mapper.readTree(resp.toJsonString());
-	assertEquals("0.24", respJson.at("/version").asText());
-	assertEquals("Tanja", respJson.at("/node").asText());
+        JsonNode respJson = mapper.readTree(resp.toJsonString());
+        assertEquals("0.24", respJson.at("/version").asText());
+        assertEquals("Tanja", respJson.at("/node").asText());
 
-	resp.addWarning(1, "Fehler 1");
-	resp.addWarning(2, "Fehler 2");
-	resp.addWarning(3, "Fehler 3");
+        resp.addWarning(1, "Fehler 1");
+        resp.addWarning(2, "Fehler 2");
+        resp.addWarning(3, "Fehler 3");
 
-	resp.addError(4, "Fehler 4");
+        resp.addError(4, "Fehler 4");
 
-	respJson = mapper.readTree(resp.toJsonString());
-	assertEquals("0.24", respJson.at("/version").asText());
-	assertEquals("Tanja", respJson.at("/node").asText());
+        respJson = mapper.readTree(resp.toJsonString());
+        assertEquals("0.24", respJson.at("/version").asText());
+        assertEquals("Tanja", respJson.at("/node").asText());
+        
+        assertEquals("Fehler 1", respJson.at("/warnings/0/1").asText());
+        assertEquals("Fehler 2", respJson.at("/warnings/1/1").asText());
+        assertEquals("Fehler 3", respJson.at("/warnings/2/1").asText());
+        assertEquals("Fehler 4", respJson.at("/errors/0/1").asText());
+    };
 
-	assertEquals("Fehler 1", respJson.at("/warnings/0/1").asText());
-	assertEquals("Fehler 2", respJson.at("/warnings/1/1").asText());
-	assertEquals("Fehler 3", respJson.at("/warnings/2/1").asText());
-	assertEquals("Fehler 4", respJson.at("/errors/0/1").asText());
+    @Test
+    public void testResponseDeserialzation () throws IOException {
+        String jsonResponse = "{\"version\":\"0.38\"}";
+        KorapResponse kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertEquals("0.38", kresp.getVersion());
+        assertNull(kresp.getName());
+        assertEquals(jsonResponse, kresp.toJsonString());
+
+        jsonResponse = "{\"version\":\"seaweed-0.49\"}";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertEquals("0.49", kresp.getVersion());
+        assertEquals("seaweed", kresp.getName());
+        assertTrue(kresp.toJsonString().contains("seaweed-0.49"));
+
+        jsonResponse = "{\"version\":\"seaweed-\"}";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertEquals("seaweed-", kresp.getVersion());
+        assertNull(kresp.getName());
+        assertTrue(kresp.toJsonString().contains("seaweed-"));
+
+        jsonResponse = "{\"timeExceeded\":true}";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertTrue(kresp.hasTimeExceeded());
+        assertTrue(kresp.hasWarnings());
+
+        jsonResponse = "{\"benchmark\":\"40.5s\", \"foo\":\"bar\"}";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertEquals("40.5s", kresp.getBenchmark());
+
+        jsonResponse = "{\"listener\":\"10.0.10.14:678\", \"foo\":\"bar\"}";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertEquals("10.0.10.14:678", kresp.getListener());
+
+        jsonResponse = "{\"node\":\"tanja\", \"foo\":\"bar\"}";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertEquals("tanja", kresp.getNode());
+
+        jsonResponse = "{\"node\":\"tanja\", \"version\":\"seaweed-0.49\", " +
+            " \"benchmark\":\"40.5s\",  \"listener\":\"10.0.10.14:678\"," +
+            "\"timeExceeded\":true }";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+        assertEquals("0.49", kresp.getVersion());
+        assertEquals("seaweed", kresp.getName());
+        assertEquals("40.5s", kresp.getBenchmark());
+        assertEquals("10.0.10.14:678", kresp.getListener());
+        assertEquals("tanja", kresp.getNode());
+        assertTrue(kresp.hasTimeExceeded());
+        assertTrue(kresp.hasWarnings());
+
+
+        jsonResponse = "{\"warnings\":[[123,\"This is a warning\"]," +
+            "[124,\"This is a second warning\"]],"+
+            "\"error\":[[125,\"This is a single error\"]], "+
+            " \"node\":\"tanja\", \"version\":\"seaweed-0.49\", " +
+            " \"benchmark\":\"40.5s\",  \"listener\":\"10.0.10.14:678\"," +
+            "\"timeExceeded\":true }";
+        kresp = mapper.readValue(jsonResponse, KorapResponse.class);
+
+        /*
+{,"version":"seaweed-0.49","timeExceeded":true,"node":"tanja","listener":"10.0.10.14:678","benchmark":"40.5s"}
+        */
+        // System.err.println(kresp.toJsonString());
     };
 };
diff --git a/src/test/java/de/ids_mannheim/korap/server/TestResource.java b/src/test/java/de/ids_mannheim/korap/server/TestResource.java
index 1096d89..c6014f7 100644
--- a/src/test/java/de/ids_mannheim/korap/server/TestResource.java
+++ b/src/test/java/de/ids_mannheim/korap/server/TestResource.java
@@ -64,73 +64,73 @@
 
     @Test
     public void testResource() throws IOException {
-	KorapResponse kresp;
+        KorapResponse kresp;
 
-	for (String i : new String[] {"00001",
-				      "00002",
-				      "00003",
-				      "00004",
-				      "00005",
-				      "00006",
-				      "02439"
-	    }) {
+        for (String i : new String[] {"00001",
+                                      "00002",
+                                      "00003",
+                                      "00004",
+                                      "00005",
+                                      "00006",
+                                      "02439"
+            }) {
 
-	    String json = StringfromFile(getClass().getResource("/wiki/" + i + ".json").getFile());
-	    kresp = target.path("/index/" + i).
-		request("application/json").
-		put(Entity.json(json), KorapResponse.class);
+            String json = StringfromFile(getClass().getResource("/wiki/" + i + ".json").getFile());
+            kresp = target.path("/index/" + i).
+                request("application/json").
+                put(Entity.json(json), KorapResponse.class);
 
-	    assertEquals(kresp.getNode(), "milena");
-	    assertFalse(kresp.hasErrors());
-	    assertFalse(kresp.hasWarnings());
-	    assertFalse(kresp.hasMessages());
-	};
+            assertEquals(kresp.getNode(), "milena");
+            assertFalse(kresp.hasErrors());
+            assertFalse(kresp.hasWarnings());
+            assertFalse(kresp.hasMessages());
+        };
 
-	kresp = target.path("/index").
-	    request("application/json").
-	    post(Entity.text(""), KorapResponse.class);
-	assertEquals(kresp.getNode(), "milena");
-	assertFalse(kresp.hasErrors());
-	assertFalse(kresp.hasWarnings());
-	assertFalse(kresp.hasMessages());
+        kresp = target.path("/index").
+            request("application/json").
+            post(Entity.text(""), KorapResponse.class);
+        assertEquals(kresp.getNode(), "milena");
+        assertFalse(kresp.hasErrors());
+        assertFalse(kresp.hasWarnings());
+        assertFalse(kresp.hasMessages());
     };
 
     @Test
     public void testCollection() throws IOException {
 
-	String json = getString(
-	    getClass().getResource("/queries/bsp-uid-example.jsonld").getFile()
+        String json = getString(
+            getClass().getResource("/queries/bsp-uid-example.jsonld").getFile()
         );
 
-	 KorapResponse kresp
-	    = target.path("/").
-	    queryParam("uid", "1").
-	    queryParam("uid", "4").
-	    request("application/json").
-	    post(Entity.json(json), KorapResponse.class);
-	 /*
-	 assertEquals(2, kresp.getTotalResults());
-	 */
-	 fail("totalResults should be implemented in KorapResponse" +
-	      " or KorapResult should be used here");
-	 assertFalse(kresp.hasErrors());
-	 assertFalse(kresp.hasWarnings());
-	 assertFalse(kresp.hasMessages());
+        KorapResponse kresp
+            = target.path("/").
+            queryParam("uid", "1").
+            queryParam("uid", "4").
+            request("application/json").
+            post(Entity.json(json), KorapResponse.class);
+        /*
+          assertEquals(2, kresp.getTotalResults());
+        */
+        fail("totalResults should be implemented in KorapResponse" +
+             " or KorapResult should be used here");
+        assertFalse(kresp.hasErrors());
+        assertFalse(kresp.hasWarnings());
+        assertFalse(kresp.hasMessages());
     };
 
     public static String getString (String path) {
-	StringBuilder contentBuilder = new StringBuilder();
-	try {
-	    BufferedReader in = new BufferedReader(new FileReader(path));
-	    String str;
-	    while ((str = in.readLine()) != null) {
-		contentBuilder.append(str);
-	    };
-	    in.close();
-	} catch (IOException e) {
-	    fail(e.getMessage());
-	}
-	return contentBuilder.toString();
+        StringBuilder contentBuilder = new StringBuilder();
+        try {
+            BufferedReader in = new BufferedReader(new FileReader(path));
+            String str;
+            while ((str = in.readLine()) != null) {
+                contentBuilder.append(str);
+            };
+            in.close();
+        }
+        catch (IOException e) {
+            fail(e.getMessage());
+        };
+        return contentBuilder.toString();
     };
-
 };