diff --git a/pom.xml b/pom.xml
index 502b5bab4eb850fda88d5c7c80cd7a3add30a59f..ca35415fb2aedacd3e960132a9afc099bb701bf8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,11 @@
     </repository>
   </repositories>
   <dependencies>
+	<dependency>
+		<groupId>org.codehaus.jettison</groupId>
+		<artifactId>jettison</artifactId>
+		<version>1.4.0</version>
+	</dependency>
     <dependency>
       <groupId>de.timmfitschen</groupId>
       <artifactId>easy-units</artifactId>
diff --git a/src/main/java/caosdb/server/CaosDBServer.java b/src/main/java/caosdb/server/CaosDBServer.java
index 07a57c5918405f7ef5f8fd6949d9dfd32bd08434..18e20aa3d35a3572560037df4b59efe3bdd3f92f 100644
--- a/src/main/java/caosdb/server/CaosDBServer.java
+++ b/src/main/java/caosdb/server/CaosDBServer.java
@@ -27,6 +27,7 @@ import caosdb.server.accessControl.OneTimeTokenRealm;
 import caosdb.server.accessControl.Principal;
 import caosdb.server.accessControl.SessionToken;
 import caosdb.server.accessControl.SessionTokenRealm;
+import caosdb.server.converter.misc.EntityJsonConverterHelper;
 import caosdb.server.converter.misc.HttpStatusConverter;
 import caosdb.server.converter.misc.MultipartContainerConverter;
 import caosdb.server.converter.xml.EntityXMLConverterHelper;
@@ -348,13 +349,20 @@ public class CaosDBServer extends Application {
       init.release();
 
       Engine.getInstance().getRegisteredConverters().clear();
-      Engine.getInstance().getRegisteredConverters().add(new DefaultConverter());
       // add XML Converters
       EntityXMLConverterHelper xmlConverter = new EntityXMLConverterHelper();
       Engine.getInstance().getRegisteredConverters().add(xmlConverter);
-      Engine.getInstance().getRegisteredConverters().add(new MultipartContainerConverter());
       Engine.getInstance().getRegisteredConverters().add(new HttpStatusConverter(xmlConverter));
 
+      // add JSON Converters
+      EntityJsonConverterHelper jsonConverter = new EntityJsonConverterHelper();
+      Engine.getInstance().getRegisteredConverters().add(jsonConverter);
+      Engine.getInstance().getRegisteredConverters().add(new HttpStatusConverter(jsonConverter));
+
+      // other
+      Engine.getInstance().getRegisteredConverters().add(new MultipartContainerConverter());
+      Engine.getInstance().getRegisteredConverters().add(new DefaultConverter());
+
       if (INSECURE) {
         runHTTPServer(port_http, initialConnections, maxTotalConnections);
       } else {
diff --git a/src/main/java/caosdb/server/converter/misc/AbstractContainerHelper.java b/src/main/java/caosdb/server/converter/misc/AbstractContainerHelper.java
index 01afb30b8e481d1b05e74ff64909baa7bd57bce5..9bace44d7756ff95ed523cc7be1f87275d175d67 100644
--- a/src/main/java/caosdb/server/converter/misc/AbstractContainerHelper.java
+++ b/src/main/java/caosdb/server/converter/misc/AbstractContainerHelper.java
@@ -66,4 +66,55 @@ public abstract class AbstractContainerHelper extends ConverterHelper {
 
     return null;
   }
+
+  /*
+   **********************************************************************
+   * The following function is stolen from {@link
+   * org.restlet.engine.converter.StatusInfoHtmlConverter} and adapted.
+   *
+   * Licensed under Apache 2.0.
+   *
+   * Author: Manuel Boillod.
+   * Copyright 2005-2019 Talend
+   * ********************************************************************
+   */
+  /**
+   * Indicates if the given variant is compatible with the media types supported by this converter.
+   *
+   * @param variant The variant.
+   * @return True if the given variant is compatible with the media types supported by this
+   *     converter.
+   */
+  protected boolean isCompatible(Variant variant) {
+    if (variant != null) {
+      for (VariantInfo v : variants) {
+        if (v.isCompatible(variant)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /*
+   **********************************************************************
+   * The following function is stolen from {@link
+   * org.restlet.engine.converter.StatusInfoHtmlConverter} and adapted.
+   *
+   * Licensed under Apache 2.0.
+   *
+   * Author: Manuel Boillod.
+   * Copyright 2005-2019 Talend
+   * ********************************************************************
+   */
+  @Override
+  public final float score(Object source, Variant target, Resource resource) {
+    float result = -1.0F;
+
+    if (source instanceof TransactionContainer && isCompatible(target)) {
+      result = 1.0F;
+    }
+
+    return result;
+  }
 }
diff --git a/src/main/java/caosdb/server/converter/misc/CaosDBStatusService.java b/src/main/java/caosdb/server/converter/misc/CaosDBStatusService.java
index f0acd7a16c38fe0281ebb40335987b31c9117934..ef0f88cd07b92573fde8229a1b8649126efc4171 100644
--- a/src/main/java/caosdb/server/converter/misc/CaosDBStatusService.java
+++ b/src/main/java/caosdb/server/converter/misc/CaosDBStatusService.java
@@ -2,6 +2,4 @@ package caosdb.server.converter.misc;
 
 import org.restlet.service.StatusService;
 
-public class CaosDBStatusService extends StatusService {
-
-}
+public class CaosDBStatusService extends StatusService {}
diff --git a/src/main/java/caosdb/server/converter/misc/EntityJsonConverterHelper.java b/src/main/java/caosdb/server/converter/misc/EntityJsonConverterHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..47af9457405755733e557b8423c4f40d63577e75
--- /dev/null
+++ b/src/main/java/caosdb/server/converter/misc/EntityJsonConverterHelper.java
@@ -0,0 +1,114 @@
+package caosdb.server.converter.misc;
+
+import caosdb.server.converter.xml.EntityXMLConverterHelper;
+import caosdb.server.entity.container.TransactionContainer;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import org.apache.commons.io.output.XmlStreamWriter;
+import org.codehaus.jettison.badgerfish.BadgerFishXMLStreamReader;
+import org.codehaus.jettison.badgerfish.BadgerFishXMLStreamWriter;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.jdom2.Document;
+import org.jdom2.JDOMException;
+import org.jdom2.input.StAXStreamBuilder;
+import org.jdom2.output.StAXStreamOutputter;
+import org.restlet.data.MediaType;
+import org.restlet.engine.resource.VariantInfo;
+import org.restlet.representation.Representation;
+import org.restlet.representation.Variant;
+import org.restlet.representation.WriterRepresentation;
+import org.restlet.resource.Resource;
+
+public class EntityJsonConverterHelper extends AbstractContainerHelper {
+
+  public static final VariantInfo VARIANT_APPLICATION_JSON =
+      new VariantInfo(MediaType.APPLICATION_JSON);
+  private EntityXMLConverterHelper xmlConverter;
+
+  public EntityJsonConverterHelper() {
+    super(VARIANT_APPLICATION_JSON);
+    this.xmlConverter = new EntityXMLConverterHelper();
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> T toObject(Representation source, Class<T> target, Resource resource)
+      throws IOException {
+
+    try {
+      Document doc = toXML(source);
+      return (T) xmlConverter.toContainer(doc, resource);
+    } catch (JSONException | XMLStreamException | JDOMException e) {
+      throw new IOException(e);
+    }
+  }
+
+  private Document toXML(Representation source)
+      throws JSONException, IOException, XMLStreamException, JDOMException {
+    JSONObject json = new JSONObject(source.getText());
+    return toXML(json);
+  }
+
+  @Override
+  public Representation toRepresentation(Object source, Variant target, Resource resource)
+      throws IOException {
+    try {
+      return toJsonRepresentation((TransactionContainer) source, resource);
+    } catch (JSONException | XMLStreamException e) {
+      throw new IOException(e);
+    }
+  }
+
+  public String toJsonString(Document doc) throws UnsupportedEncodingException, XMLStreamException {
+    ByteArrayOutputStream o = new ByteArrayOutputStream();
+    BadgerFishXMLStreamWriter w = new BadgerFishXMLStreamWriter(new XmlStreamWriter(o));
+
+    StAXStreamOutputter outputter2 = new StAXStreamOutputter();
+    outputter2.getFormat().setExpandEmptyElements(true);
+    outputter2.output(doc, w);
+
+    return o.toString("utf-8");
+  }
+
+  public JSONObject toJson(Document doc) throws IOException, JSONException, XMLStreamException {
+    return new JSONObject(toJsonString(doc));
+  }
+
+  public Document toXML(JSONObject json)
+      throws JDOMException, IOException, XMLStreamException, JSONException {
+
+    XMLStreamReader r = new BadgerFishXMLStreamReader(json);
+
+    StAXStreamBuilder b = new StAXStreamBuilder();
+    Document doc = b.build(r);
+
+    return doc;
+  }
+
+  private Representation toJsonRepresentation(TransactionContainer source, Resource resource)
+      throws IOException, JSONException, XMLStreamException {
+    Document document = xmlConverter.toDocument(source, resource);
+    JSONObject jsonObject = toJson(document);
+    return toJsonRepresentation(jsonObject, resource);
+  }
+
+  private Representation toJsonRepresentation(JSONObject jsonObject, Resource resource) {
+    // TODO move to own class
+    return new WriterRepresentation(MediaType.APPLICATION_JSON) {
+
+      @Override
+      public void write(Writer writer) throws IOException {
+        try {
+          jsonObject.write(writer);
+        } catch (JSONException e) {
+          throw new IOException(e);
+        }
+      }
+    };
+  }
+}
diff --git a/src/main/java/caosdb/server/converter/misc/HttpStatusConverter.java b/src/main/java/caosdb/server/converter/misc/HttpStatusConverter.java
index 926a61e1ea54645584290800850b488ffbe8c829..d58f0280eb2e8a94228b9b876c7505e48ec7e000 100644
--- a/src/main/java/caosdb/server/converter/misc/HttpStatusConverter.java
+++ b/src/main/java/caosdb/server/converter/misc/HttpStatusConverter.java
@@ -1,5 +1,8 @@
 package caosdb.server.converter.misc;
 
+import caosdb.server.entity.Message;
+import caosdb.server.entity.container.TransactionContainer;
+import caosdb.server.utils.ServerMessages;
 import java.io.IOException;
 import java.util.List;
 import org.apache.shiro.SecurityUtils;
@@ -11,9 +14,6 @@ import org.restlet.engine.resource.VariantInfo;
 import org.restlet.representation.Representation;
 import org.restlet.representation.Variant;
 import org.restlet.resource.Resource;
-import caosdb.server.entity.Message;
-import caosdb.server.entity.container.TransactionContainer;
-import caosdb.server.utils.ServerMessages;
 
 public class HttpStatusConverter extends ConverterHelper {
 
@@ -88,8 +88,12 @@ public class HttpStatusConverter extends ConverterHelper {
     if (status.getCode() == 500) {
       t.addMessage(ServerMessages.UNKNOWN_ERROR(requestId));
     } else {
-      t.addMessage(new Message((Status.valueOf(status.getCode()).isError() ? "Error" : "Info"),
-          status.getCode(), status.getReasonPhrase(), status.getDescription()));
+      t.addMessage(
+          new Message(
+              (Status.valueOf(status.getCode()).isError() ? "Error" : "Info"),
+              status.getCode(),
+              status.getReasonPhrase(),
+              status.getDescription()));
     }
     return containerConverter.toRepresentation(t, target, resource);
   }
diff --git a/src/main/java/caosdb/server/converter/misc/MultipartContainerConverter.java b/src/main/java/caosdb/server/converter/misc/MultipartContainerConverter.java
index 7a336295eb39fe507667e9fc5036c4daa37f64de..cd5b7b3fc9f28f00e491ead3f008692c9a7b0c0e 100644
--- a/src/main/java/caosdb/server/converter/misc/MultipartContainerConverter.java
+++ b/src/main/java/caosdb/server/converter/misc/MultipartContainerConverter.java
@@ -39,12 +39,6 @@ public class MultipartContainerConverter extends AbstractContainerHelper {
     super(VARIANT_MULTIPART_FORMDATA);
   }
 
-  @Override
-  public float score(Object source, Variant target, Resource resource) {
-    // this class only converts from multipart/form-data to Containers.
-    return -1.0F;
-  }
-
   @Override
   public <T> T toObject(Representation source, Class<T> target, Resource resource)
       throws IOException {
diff --git a/src/main/java/caosdb/server/converter/xml/EntityXMLConverterHelper.java b/src/main/java/caosdb/server/converter/xml/EntityXMLConverterHelper.java
index 5baaea4cc1ce780962f516c44e8ba50529db0d94..69c316331415e2a6950a6c038b69739d4d04fe87 100644
--- a/src/main/java/caosdb/server/converter/xml/EntityXMLConverterHelper.java
+++ b/src/main/java/caosdb/server/converter/xml/EntityXMLConverterHelper.java
@@ -1,5 +1,12 @@
 package caosdb.server.converter.xml;
 
+import caosdb.server.accessControl.AuthenticationUtils;
+import caosdb.server.accessControl.Principal;
+import caosdb.server.accessControl.UserSources;
+import caosdb.server.converter.misc.AbstractContainerHelper;
+import caosdb.server.entity.Entity;
+import caosdb.server.entity.container.TransactionContainer;
+import caosdb.server.resource.JdomRepresentation;
 import java.io.IOException;
 import java.util.Collection;
 import org.apache.shiro.subject.Subject;
@@ -14,15 +21,6 @@ import org.restlet.representation.Representation;
 import org.restlet.representation.Variant;
 import org.restlet.resource.Resource;
 import org.restlet.resource.ResourceException;
-import caosdb.server.accessControl.AuthenticationUtils;
-import caosdb.server.accessControl.Principal;
-import caosdb.server.accessControl.UserSources;
-import caosdb.server.converter.misc.AbstractContainerHelper;
-import caosdb.server.entity.Entity;
-import caosdb.server.entity.EntityInterface;
-import caosdb.server.entity.container.Container;
-import caosdb.server.entity.container.TransactionContainer;
-import caosdb.server.resource.JdomRepresentation;
 
 public class EntityXMLConverterHelper extends AbstractContainerHelper {
 
@@ -39,9 +37,9 @@ public class EntityXMLConverterHelper extends AbstractContainerHelper {
   @Override
   public <T> T toObject(Representation source, Class<T> target, Resource resource)
       throws IOException {
-    Document xml;
     try {
-      xml = xmlParser.parse(source.getStream());
+      Document xml = toDocument(source);
+      return (T) toContainer(xml, resource);
     } catch (JDOMException e) {
       throw new ResourceException(
           new Status(Status.CLIENT_ERROR_BAD_REQUEST, "Could not parse XML."),
@@ -49,10 +47,13 @@ public class EntityXMLConverterHelper extends AbstractContainerHelper {
           resource.getRequest(),
           resource.getResponse());
     }
-    return (T) createContainer(xml, resource);
   }
 
-  private Container<? extends EntityInterface> createContainer(Document xml, Resource resource) {
+  public Document toDocument(Representation source) throws JDOMException, IOException {
+    return xmlParser.parse(source.getStream());
+  }
+
+  public TransactionContainer toContainer(Document xml, Resource resource) {
     TransactionContainer result = createContainer(resource);
     for (Element e : xml.getRootElement().getChildren()) {
       result.add(new Entity(e));
@@ -70,9 +71,11 @@ public class EntityXMLConverterHelper extends AbstractContainerHelper {
   private Representation toJdomRepresentation(TransactionContainer container, Resource resource) {
     Document doc = toDocument(container, resource);
 
-    String xsl = resource.getResponseAttributes().get("xsl").toString();
-    if (xsl != null) {
-      addStyleSheet(doc, xsl);
+    if (resource != null) {
+      Object xsl = resource.getResponseAttributes().get("xsl");
+      if (xsl != null) {
+        addStyleSheet(doc, xsl.toString());
+      }
     }
 
     return new JdomRepresentation(doc, "  ");
@@ -98,13 +101,19 @@ public class EntityXMLConverterHelper extends AbstractContainerHelper {
    *   <li>A timestamp
    *   <li>The URI to this resource.
    */
-  protected Document toDocument(TransactionContainer container, Resource resource) {
+  public Document toDocument(TransactionContainer container, Resource resource) {
     final Element root = new Element("Response");
 
     addUserInfo(root, container.getOwner());
-    root.setAttribute("srid", container.getRequestId());
-    root.setAttribute("timestamp", container.getTimestamp().toString());
-    root.setAttribute("baseuri", resource.getRootRef().toString());
+    if (container.getRequestId() != null) {
+      root.setAttribute("srid", container.getRequestId());
+    }
+    if (container.getTimestamp() != null) {
+      root.setAttribute("timestamp", container.getTimestamp().toString());
+    }
+    if (resource != null) {
+      root.setAttribute("baseuri", resource.getRootRef().toString());
+    }
 
     container.addToElement(root);
 
@@ -162,50 +171,4 @@ public class EntityXMLConverterHelper extends AbstractContainerHelper {
     userInfo.setAttribute("username", ((Principal) user.getPrincipal()).getUsername());
     userInfo.setAttribute("realm", ((Principal) user.getPrincipal()).getRealm());
   }
-
-  /*
-   **********************************************************************
-   * The following function is stolen from {@link
-   * org.restlet.engine.converter.StatusInfoHtmlConverter} and adapted.
-   *
-   * Licensed under Apache 2.0.
-   *
-   * Author: Manuel Boillod.
-   * Copyright 2005-2019 Talend
-   * ********************************************************************
-   */
-  /**
-   * Indicates if the given variant is compatible with the media types supported by this converter.
-   *
-   * @param variant The variant.
-   * @return True if the given variant is compatible with the media types supported by this
-   *     converter.
-   */
-  protected boolean isCompatible(Variant variant) {
-    return (variant != null)
-        && (VARIANT_TEXT_XML.isCompatible(variant)
-            || VARIANT_APPLICATION_XML.isCompatible(variant));
-  }
-
-  /*
-   **********************************************************************
-   * The following function is stolen from {@link
-   * org.restlet.engine.converter.StatusInfoHtmlConverter} and adapted.
-   *
-   * Licensed under Apache 2.0.
-   *
-   * Author: Manuel Boillod.
-   * Copyright 2005-2019 Talend
-   * ********************************************************************
-   */
-  @Override
-  public float score(Object source, Variant target, Resource resource) {
-    float result = -1.0F;
-
-    if (source instanceof TransactionContainer && isCompatible(target)) {
-      result = 1.0F;
-    }
-
-    return result;
-  }
 }
diff --git a/src/main/java/caosdb/server/entity/Message.java b/src/main/java/caosdb/server/entity/Message.java
index b57d6166df3df7a8913605a0af105907bd7be3f6..63b3ae4ad3d20bd5eb87e183e52232af77004389 100644
--- a/src/main/java/caosdb/server/entity/Message.java
+++ b/src/main/java/caosdb/server/entity/Message.java
@@ -22,9 +22,9 @@
  */
 package caosdb.server.entity;
 
+import caosdb.server.entity.xml.ToElementable;
 import org.jdom2.Element;
 import org.restlet.data.Status;
-import caosdb.server.entity.xml.ToElementable;
 
 public class Message extends Exception implements Comparable<Message>, ToElementable {
 
@@ -40,9 +40,13 @@ public class Message extends Exception implements Comparable<Message>, ToElement
     Error,
     Info
   };
-  
+
   public Message(Status status) {
-    this(status.isError()? "Error" : "Info", status.getCode(), status.getReasonPhrase(), status.getDescription());
+    this(
+        status.isError() ? "Error" : "Info",
+        status.getCode(),
+        status.getReasonPhrase(),
+        status.getDescription());
   }
 
   @Override
diff --git a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java
index 339e6ac01283fbad53a8ba4f9fe6004fa7f75b29..aac90f5a28cac89fe0ec4fe3b26fef33a7fb4f63 100644
--- a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java
+++ b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java
@@ -23,6 +23,7 @@
  */
 package caosdb.server.resource;
 
+import caosdb.server.utils.WebinterfaceUtils;
 import java.io.IOException;
 import java.util.List;
 import java.util.logging.Level;
@@ -34,7 +35,6 @@ import org.restlet.engine.application.StatusInfo;
 import org.restlet.representation.Representation;
 import org.restlet.representation.Variant;
 import org.restlet.resource.ServerResource;
-import caosdb.server.utils.WebinterfaceUtils;
 
 /**
  * Base class for all CaosDB Server Resources.
@@ -43,6 +43,10 @@ import caosdb.server.utils.WebinterfaceUtils;
  */
 public abstract class AbstractCaosDBServerResource extends ServerResource {
 
+  public AbstractCaosDBServerResource() {
+    this.getConnegService().setStrict(true);
+  }
+
   private WebinterfaceUtils utils;
 
   /** Return the {@link WebinterfaceUtils} instance for this resource. */
@@ -93,38 +97,37 @@ public abstract class AbstractCaosDBServerResource extends ServerResource {
   public final String getSRID() {
     return getRequest().getAttributes().get("SRID").toString();
   }
-  
+
   /*
    * Stolen from Restlet and adapted to our needs.
    */
   @Override
   protected void doCatch(Throwable throwable) {
-        Level level = Level.INFO;
-        Status status = getStatusService().toStatus(throwable, this);
-
-        if (status.isServerError()) {
-            level = Level.SEVERE;
-        } else if (status.isConnectorError()) {
-            level = Level.INFO;
-        } else if (status.isClientError()) {
-            level = Level.FINE;
-        }
-
-        getLogger().log(level, "Exception or error caught in server resource",
-                throwable);
-
-        if (getResponse() != null) {
-          getResponse().setStatus(status);
-
-            List<Variant> variants = getVariants(getMethod());
-            Variant preferredVariant = getPreferredVariant(variants);
-            try {
-              Representation errorEntity;
-              errorEntity = toRepresentation(new StatusInfo(status), preferredVariant);
-              getResponse().setEntity(errorEntity);
-            } catch (IOException e) {
-              getLogger().log(Level.SEVERE, "Exception during serialization of another error.", e);
-            }
-        }
+    Level level = Level.INFO;
+    Status status = getStatusService().toStatus(throwable, this);
+
+    if (status.isServerError()) {
+      level = Level.SEVERE;
+    } else if (status.isConnectorError()) {
+      level = Level.INFO;
+    } else if (status.isClientError()) {
+      level = Level.FINE;
+    }
+
+    getLogger().log(level, "Exception or error caught in server resource", throwable);
+
+    if (getResponse() != null) {
+      getResponse().setStatus(status);
+
+      List<Variant> variants = getVariants(getMethod());
+      Variant preferredVariant = getPreferredVariant(variants);
+      try {
+        Representation errorEntity;
+        errorEntity = toRepresentation(new StatusInfo(status), preferredVariant);
+        getResponse().setEntity(errorEntity);
+      } catch (IOException e) {
+        getLogger().log(Level.SEVERE, "Exception during serialization of another error.", e);
+      }
+    }
   }
 }
diff --git a/src/main/java/caosdb/server/resource/FileSystemResource.java b/src/main/java/caosdb/server/resource/FileSystemResource.java
index c066e1a70aace980417fa89780cc5adaa7177c3a..cc8d8df75d96ea4b53ce26a5b1a2ec859d543d6d 100644
--- a/src/main/java/caosdb/server/resource/FileSystemResource.java
+++ b/src/main/java/caosdb/server/resource/FileSystemResource.java
@@ -24,17 +24,7 @@ package caosdb.server.resource;
 
 import static caosdb.server.FileSystem.getFromFileSystem;
 import static java.net.URLDecoder.decode;
-import java.io.File;
-import java.io.IOException;
-import org.jdom2.Attribute;
-import org.jdom2.Document;
-import org.jdom2.Element;
-import org.jdom2.JDOMException;
-import org.restlet.data.Disposition;
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.representation.FileRepresentation;
-import org.restlet.representation.Representation;
+
 import caosdb.server.database.backend.implementation.MySQL.ConnectionException;
 import caosdb.server.database.exceptions.EntityDoesNotExistException;
 import caosdb.server.database.misc.TransactionBenchmark;
@@ -49,6 +39,17 @@ import caosdb.server.transaction.RetrieveSparseEntityByPath;
 import caosdb.server.transaction.Transaction;
 import caosdb.server.utils.FileUtils;
 import caosdb.server.utils.ServerMessages;
+import java.io.File;
+import java.io.IOException;
+import org.jdom2.Attribute;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.restlet.data.Disposition;
+import org.restlet.data.MediaType;
+import org.restlet.data.Status;
+import org.restlet.representation.FileRepresentation;
+import org.restlet.representation.Representation;
 
 /**
  * Download files via GET method from the file system directly without making the detour through the
@@ -221,5 +222,4 @@ public class FileSystemResource extends XMLServerResource {
     this.setStatus(org.restlet.data.Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
     return null;
   }
-  
 }
diff --git a/src/main/java/caosdb/server/resource/JdomRepresentation.java b/src/main/java/caosdb/server/resource/JdomRepresentation.java
index 1eef69e6b8d5206763026f7201543baacb885d13..29210904645dc3f2e2c0d1630c87e312b670d0d0 100644
--- a/src/main/java/caosdb/server/resource/JdomRepresentation.java
+++ b/src/main/java/caosdb/server/resource/JdomRepresentation.java
@@ -23,7 +23,6 @@
 package caosdb.server.resource;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.io.Writer;
 import org.jdom2.Document;
 import org.jdom2.output.Format;
@@ -78,17 +77,4 @@ public class JdomRepresentation extends WriterRepresentation {
       outputter.output(this.document, writer);
     }
   }
-
-  @Override
-  public void write(final OutputStream out) throws IOException {
-    if (this.document != null && this.document.hasRootElement()) {
-      final XMLOutputter outputter = new XMLOutputter();
-      final Format newFormat = Format.getPrettyFormat();
-      if (this.indent != null) {
-        newFormat.setIndent(this.indent);
-      }
-      outputter.setFormat(newFormat);
-      outputter.output(this.document, out);
-    }
-  }
 }
diff --git a/src/main/java/caosdb/server/resource/XMLServerResource.java b/src/main/java/caosdb/server/resource/XMLServerResource.java
index 70b69b8d20bf7def01849372454858c6b18cda22..66ed8c5ba5cf61b3e44d5de6d29252507f9c43d2 100644
--- a/src/main/java/caosdb/server/resource/XMLServerResource.java
+++ b/src/main/java/caosdb/server/resource/XMLServerResource.java
@@ -19,6 +19,14 @@
  */
 package caosdb.server.resource;
 
+import caosdb.server.CaosDBException;
+import caosdb.server.accessControl.AuthenticationUtils;
+import caosdb.server.accessControl.Principal;
+import caosdb.server.accessControl.UserSources;
+import caosdb.server.converter.xml.XMLParser;
+import caosdb.server.database.backend.implementation.MySQL.ConnectionException;
+import caosdb.server.entity.Message;
+import caosdb.server.utils.ServerMessages;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.NoSuchAlgorithmException;
@@ -39,14 +47,6 @@ import org.restlet.resource.Delete;
 import org.restlet.resource.Get;
 import org.restlet.resource.Post;
 import org.restlet.resource.Put;
-import caosdb.server.CaosDBException;
-import caosdb.server.accessControl.AuthenticationUtils;
-import caosdb.server.accessControl.Principal;
-import caosdb.server.accessControl.UserSources;
-import caosdb.server.converter.xml.XMLParser;
-import caosdb.server.database.backend.implementation.MySQL.ConnectionException;
-import caosdb.server.entity.Message;
-import caosdb.server.utils.ServerMessages;
 
 /**
  * This is a temporary bridge class. It contains all code which is necessary for any resources that
@@ -326,14 +326,13 @@ public abstract class XMLServerResource extends AbstractCaosDBServerResource {
     }
     return root;
   }
-  
+
   public Representation toJdomRepresentation(Document doc) {
     String xsl = getXSLScript();
-    if(xsl!=null) {
-      addStyleSheet(doc, xsl); 
+    if (xsl != null) {
+      addStyleSheet(doc, xsl);
     }
     return new JdomRepresentation(doc, "  ");
-      
   }
 
   /** adds the xslt processing instruction to the document. */
@@ -342,6 +341,4 @@ public abstract class XMLServerResource extends AbstractCaosDBServerResource {
         new ProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"" + xslPath + "\" ");
     document.getContent().add(0, pi);
   }
- 
- 
 }
diff --git a/src/main/java/caosdb/server/resource/transaction/AbstractEntityResource.java b/src/main/java/caosdb/server/resource/transaction/AbstractEntityResource.java
index a1f072814b9b882b170adc345fccb3590914fc47..e5ca0e8b05711ef3229eb7ac70146ea016ee1748 100644
--- a/src/main/java/caosdb/server/resource/transaction/AbstractEntityResource.java
+++ b/src/main/java/caosdb/server/resource/transaction/AbstractEntityResource.java
@@ -40,7 +40,7 @@ public abstract class AbstractEntityResource extends AbstractCaosDBServerResourc
   }
 
   @Get
-  public final TransactionContainer httpGetInChildClass()
+  public final TransactionContainer retrieve()
       throws ConnectionException, IOException, SQLException, CaosDBException,
           NoSuchAlgorithmException, Exception {
 
diff --git a/src/test/java/caosdb/server/converter/TestJsonXmlConversion.java b/src/test/java/caosdb/server/converter/TestJsonXmlConversion.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a06dd87b3e84bbe0cae3aeb7db6711485468de0
--- /dev/null
+++ b/src/test/java/caosdb/server/converter/TestJsonXmlConversion.java
@@ -0,0 +1,87 @@
+package caosdb.server.converter;
+
+import static org.junit.Assert.assertEquals;
+
+import caosdb.server.converter.misc.EntityJsonConverterHelper;
+import java.io.IOException;
+import java.io.StringReader;
+import javax.xml.stream.XMLStreamException;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+import org.junit.Test;
+
+public class TestJsonXmlConversion {
+
+  @Test
+  public void testSimple() throws IOException, JDOMException, JSONException, XMLStreamException {
+    EntityJsonConverterHelper c = new EntityJsonConverterHelper();
+    Element root = new Element("Root");
+    Document doc = new Document(root);
+    org.codehaus.jettison.json.JSONObject json = c.toJson(doc);
+    assertEquals("{\"Root\":{}}", json.toString());
+
+    root = c.toXML(json).getRootElement();
+    assertEquals("Root", root.getName());
+  }
+
+  @Test
+  public void testAttribute() throws IOException, JDOMException, JSONException, XMLStreamException {
+    EntityJsonConverterHelper c = new EntityJsonConverterHelper();
+    Element root = new Element("Root");
+    root.setAttribute("attr", "val");
+    assertEquals("val", root.getAttributeValue("attr"));
+
+    Document doc = new Document(root);
+    JSONObject json = c.toJson(doc);
+    String attr = json.getJSONObject("Root").getString("@attr");
+    assertEquals("val", attr);
+
+    root = c.toXML(json).getRootElement();
+    assertEquals("Root", root.getName());
+
+    assertEquals("val", root.getAttributeValue("attr"));
+  }
+
+  @Test
+  public void testList() throws IOException, JDOMException, JSONException, XMLStreamException {
+    EntityJsonConverterHelper c = new EntityJsonConverterHelper();
+    Element root = new Element("Root");
+    for (int i = 0; i < 3; i++) {
+      Element child = new Element("Child");
+      child.setAttribute("id", Integer.toString(i));
+      root.addContent(child);
+    }
+    assertEquals(
+        "[[Element: <Child/>], [Element: <Child/>], [Element: <Child/>]]",
+        root.getChildren().toString());
+
+    Document doc = new Document(root);
+    JSONObject json = c.toJson(doc);
+    JSONArray child = json.getJSONObject("Root").getJSONArray("Child");
+    assertEquals("[{\"@id\":\"0\"},{\"@id\":\"1\"},{\"@id\":\"2\"}]", child.toString());
+
+    root = c.toXML(json).getRootElement();
+    assertEquals("Root", root.getName());
+
+    assertEquals(
+        "[[Element: <Child/>], [Element: <Child/>], [Element: <Child/>]]",
+        root.getChildren().toString());
+  }
+
+  @Test
+  public void testJettison() throws JDOMException, IOException, JSONException, XMLStreamException {
+    String xml = "<A><B c=\"d\"/><B c=\"e\"/></A>";
+
+    SAXBuilder b = new SAXBuilder();
+    StringReader r = new StringReader(xml);
+    Document doc = b.build(r);
+
+    EntityJsonConverterHelper c = new EntityJsonConverterHelper();
+    assertEquals("{\"A\":{\"B\":[{\"@c\":\"d\"},{\"@c\":\"e\"}]}}", c.toJsonString(doc));
+  }
+}
diff --git a/src/test/java/caosdb/server/resource/TestScriptingResource.java b/src/test/java/caosdb/server/resource/TestScriptingResource.java
index 2edfb82b53b56324996293a469fadf807264d86c..6a979c926e7179ae7ab13b9f81f3dd49ec9949f8 100644
--- a/src/test/java/caosdb/server/resource/TestScriptingResource.java
+++ b/src/test/java/caosdb/server/resource/TestScriptingResource.java
@@ -194,6 +194,7 @@ public class TestScriptingResource {
     entity.setMediaType(MediaType.TEXT_ALL);
     Request request = new Request(Method.POST, "../test", entity);
     request.getAttributes().put("SRID", "asdf1234");
+    request.getClientInfo().accept(MediaType.ALL);
     request.setDate(new Date());
     resource.init(null, request, new Response(null));
     resource.handle();
@@ -208,6 +209,7 @@ public class TestScriptingResource {
     Representation entity = new StringRepresentation("asdf");
     entity.setMediaType(MediaType.TEXT_ALL);
     Request request = new Request(Method.POST, "../test", entity);
+    request.getClientInfo().accept(MediaType.ALL);
     request.setRootRef(new Reference("bla"));
     request.getAttributes().put("SRID", "asdf1234");
     request.setDate(new Date());