diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4a4083ceccc44ec0806916c47a1eb0b055f9484c..fa6f59e5281bfcb9b4fbc2ad1e558afbcdf00071 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -81,6 +81,7 @@ test:server:
     dependencies:
         - build:server
     script:
+        - echo "defaultRealm = CaosDB" > conf/usersources.ini
         - mvn test
 
 ###########
diff --git a/README.md b/README.md
index 6af9cfc463d86618ab0457a4c32ee51bc93046a0..dab09859fc312a91641154515ec9b98e777dae6c 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+<!--THIS FILE HAS BEEN GENERATED BY A SCRIPT. PLEASE DON'T CHANGE IT MANUALLY.-->
+
 # Welcome
 
 This is the **CaosDB Server** repository and a part of the CaosDB project.
diff --git a/caosdb-webui b/caosdb-webui
index 7df3c8cdf945e5b98df8b04a084fabbdaf058946..32fa3b8af945d4d0bf4e98818b2456bdc8f375c0 160000
--- a/caosdb-webui
+++ b/caosdb-webui
@@ -1 +1 @@
-Subproject commit 7df3c8cdf945e5b98df8b04a084fabbdaf058946
+Subproject commit 32fa3b8af945d4d0bf4e98818b2456bdc8f375c0
diff --git a/src/main/java/caosdb/datetime/UTCDateTime.java b/src/main/java/caosdb/datetime/UTCDateTime.java
index 4da38a4f4ca93635533b305d608811494a657bff..846c8f9f266d4b834314b95e00973993d9031224 100644
--- a/src/main/java/caosdb/datetime/UTCDateTime.java
+++ b/src/main/java/caosdb/datetime/UTCDateTime.java
@@ -213,6 +213,9 @@ public class UTCDateTime implements Interval {
 
     // june 2015
     addLeapSecond(2015, 06, 30);
+
+    // dec 2016
+    addLeapSecond(2016, 12, 31);
   }
 
   public long getUTCSeconds() {
diff --git a/src/main/java/caosdb/server/CaosAuthenticator.java b/src/main/java/caosdb/server/CaosAuthenticator.java
index 87290564a0d6bc26d5d976d528e006f87ed34fd5..0cc6cc3ddfedf6e45a708d3eeed2ed99b1b076d2 100644
--- a/src/main/java/caosdb/server/CaosAuthenticator.java
+++ b/src/main/java/caosdb/server/CaosAuthenticator.java
@@ -29,9 +29,7 @@ import caosdb.server.resource.DefaultResource;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.AccountException;
 import org.apache.shiro.authc.AuthenticationException;
-import org.apache.shiro.authc.CredentialsException;
 import org.apache.shiro.subject.Subject;
 import org.restlet.Context;
 import org.restlet.Request;
@@ -62,13 +60,15 @@ public class CaosAuthenticator extends Authenticator {
       if (sessionToken != null) {
         subject.login(sessionToken);
       }
-    } catch (final CredentialsException e) {
-      logger.log(Level.INFO, "LOGIN_FAILED", e);
-    } catch (final AccountException e) {
-      logger.log(Level.INFO, "LOGIN_FAILED", e);
-    } catch (final AuthenticationException e) {
+    } catch (AuthenticationException e) {
       logger.log(Level.INFO, "LOGIN_FAILED", e);
     }
+    // anonymous users
+    if (!subject.isAuthenticated()
+        && CaosDBServer.getServerProperty(ServerProperties.KEY_AUTH_OPTIONAL)
+            .equalsIgnoreCase("TRUE")) {
+      subject.login(AuthenticationUtils.ANONYMOUS_USER);
+    }
     return subject.isAuthenticated();
   }
 
@@ -91,10 +91,6 @@ public class CaosAuthenticator extends Authenticator {
       if (oneTimeToken != null) {
         subject.login(oneTimeToken);
       }
-    } catch (final CredentialsException e) {
-      logger.log(Level.INFO, "LOGIN_FAILED", e);
-    } catch (final AccountException e) {
-      logger.log(Level.INFO, "LOGIN_FAILED", e);
     } catch (final AuthenticationException e) {
       logger.log(Level.INFO, "LOGIN_FAILED", e);
     }
diff --git a/src/main/java/caosdb/server/CaosDBServer.java b/src/main/java/caosdb/server/CaosDBServer.java
index 811137780cee9c83e787af92d0d9f50b67272ed0..2aa6ad3a5b6d89aa74bc10d2654327f5919aca45 100644
--- a/src/main/java/caosdb/server/CaosDBServer.java
+++ b/src/main/java/caosdb/server/CaosDBServer.java
@@ -19,6 +19,7 @@
  */
 package caosdb.server;
 
+import caosdb.server.accessControl.AnonymousRealm;
 import caosdb.server.accessControl.AuthenticationUtils;
 import caosdb.server.accessControl.CaosDBAuthorizingRealm;
 import caosdb.server.accessControl.CaosDBDefaultRealm;
@@ -47,6 +48,7 @@ import caosdb.server.resource.PermissionRulesResource;
 import caosdb.server.resource.RolesResource;
 import caosdb.server.resource.ScriptingResource;
 import caosdb.server.resource.ServerLogsResource;
+import caosdb.server.resource.ServerPropertiesResource;
 import caosdb.server.resource.TestCaseFileSystemResource;
 import caosdb.server.resource.TestCaseResource;
 import caosdb.server.resource.ThumbnailsResource;
@@ -110,10 +112,7 @@ public class CaosDBServer extends Application {
   private static boolean INSECURE = false;
 
   public static String getServerProperty(final String key) {
-    if (SERVER_PROPERTIES == null) {
-      SERVER_PROPERTIES = ServerProperties.initServerProperties();
-    }
-    return SERVER_PROPERTIES.getProperty(key);
+    return getServerProperties().getProperty(key);
   }
 
   /**
@@ -152,9 +151,10 @@ public class CaosDBServer extends Application {
     mainSec.put("SessionTokenValidator", SessionTokenRealm.class.getCanonicalName());
     mainSec.put("OneTimeTokenValidator", OneTimeTokenRealm.class.getCanonicalName());
     mainSec.put("CaosDBAuthorizingRealm", CaosDBAuthorizingRealm.class.getCanonicalName());
+    mainSec.put("AnonymousRealm", AnonymousRealm.class.getCanonicalName());
     mainSec.put(
         "securityManager.realms",
-        "$CaosDB, $SessionTokenValidator, $OneTimeTokenValidator, $CaosDBAuthorizingRealm");
+        "$CaosDB, $SessionTokenValidator, $OneTimeTokenValidator, $CaosDBAuthorizingRealm, $AnonymousRealm");
 
     // disable shiro's default session management. We have quasi-stateless
     // sessions
@@ -277,17 +277,14 @@ public class CaosDBServer extends Application {
 
     // Create an application (this class).
     final Application application = new CaosDBServer();
-    application.getStatusService().setContactEmail("timm.fitschen@ds.mpg.de");
     application
         .getStatusService()
-        .setHomeRef(new Reference(getServerProperty(ServerProperties.KEY_CONTEXT_ROOT) + "/"));
-
-    // Attach the application to the component with a defined contextRoot.
-    application.getStatusService().setContactEmail("timm.fitschen@ds.mpg.de");
+        .setContactEmail(getServerProperty(ServerProperties.KEY_ADMIN_EMAIL));
     application
         .getStatusService()
         .setHomeRef(new Reference(getServerProperty(ServerProperties.KEY_CONTEXT_ROOT) + "/"));
 
+    // Attach the application to the component with a defined contextRoot.
     component
         .getDefaultHost()
         .attach(getServerProperty(ServerProperties.KEY_CONTEXT_ROOT), application);
@@ -433,7 +430,8 @@ public class CaosDBServer extends Application {
           private void setSessionCookies(final Response response) {
 
             final Subject subject = SecurityUtils.getSubject();
-            if (subject.isAuthenticated()) {
+            if (subject.isAuthenticated()
+                && subject.getPrincipal() != AuthenticationUtils.ANONYMOUS_USER.getPrincipal()) {
               final SessionToken sessionToken =
                   SessionToken.generate((Principal) subject.getPrincipal(), null);
 
@@ -578,6 +576,7 @@ public class CaosDBServer extends Application {
         .setMatchingMode(Template.MODE_STARTS_WITH);
     protectedRouter.attach("/login?username={username}", AuthenticationResource.class);
     protectedRouter.attach("/logout", LogoutResource.class);
+    protectedRouter.attach("/_server_properties", ServerPropertiesResource.class);
     protectedRouter.attachDefault(DefaultResource.class);
 
     /*
@@ -708,6 +707,13 @@ public class CaosDBServer extends Application {
     }
     SERVER_PROPERTIES.setProperty(key, value);
   }
+
+  public static Properties getServerProperties() {
+    if (SERVER_PROPERTIES == null) {
+      SERVER_PROPERTIES = ServerProperties.initServerProperties();
+    }
+    return SERVER_PROPERTIES;
+  }
 }
 
 class CaosDBComponent extends Component {
diff --git a/src/main/java/caosdb/server/ServerProperties.java b/src/main/java/caosdb/server/ServerProperties.java
index 011c9a6f599b596895298b2b11b54f9d7351665c..a4f93ec1c1207e21b0d282974fbf23c1a028053e 100644
--- a/src/main/java/caosdb/server/ServerProperties.java
+++ b/src/main/java/caosdb/server/ServerProperties.java
@@ -137,6 +137,7 @@ public class ServerProperties extends Properties {
     serverProperties.setProperty(KEY_USER_SOURCES_INI_FILE, basepath + "/conf/usersources.ini");
     serverProperties.setProperty(KEY_USER_FOLDERS, "FALSE");
     serverProperties.setProperty(KEY_NEW_USER_DEFAULT_ACTIVITY, "INACTIVE");
+    serverProperties.setProperty(KEY_AUTH_OPTIONAL, "FALSE");
 
     serverProperties.setProperty(KEY_MYSQL_HOST, "localhost");
     serverProperties.setProperty(KEY_MYSQL_PORT, "3306");
@@ -144,7 +145,7 @@ public class ServerProperties extends Properties {
     serverProperties.setProperty(KEY_MYSQL_USER_NAME, "CaosDB");
     serverProperties.setProperty(KEY_MYSQL_USER_PASSWORD, "CaosDB");
 
-    serverProperties.setProperty(KEY_MYSQL_SCHEMA_VERSION, "v2.0.30");
+    serverProperties.setProperty(KEY_MYSQL_SCHEMA_VERSION, "v2.1.0");
 
     serverProperties.setProperty(KEY_BASE_PATH, basepath);
     serverProperties.setProperty(KEY_CONTEXT_ROOT, "");
diff --git a/src/main/java/caosdb/server/ServerPropertiesSerializer.java b/src/main/java/caosdb/server/ServerPropertiesSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..10189f99e2ff30a2d9306ad9dc007810607747dd
--- /dev/null
+++ b/src/main/java/caosdb/server/ServerPropertiesSerializer.java
@@ -0,0 +1,36 @@
+package caosdb.server;
+
+import caosdb.server.utils.Serializer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import org.jdom2.Element;
+
+public class ServerPropertiesSerializer implements Serializer<Properties, Element> {
+
+  private boolean sort;
+
+  public ServerPropertiesSerializer(boolean sort) {
+    this.sort = sort;
+  }
+
+  public ServerPropertiesSerializer() {
+    this(true);
+  }
+
+  @Override
+  public Element serialize(Properties object) {
+    Element root = new Element("Properties");
+    List<String> names = new ArrayList<>(object.stringPropertyNames());
+    if (sort) {
+      Collections.sort(names);
+    }
+    for (String prop : names) {
+      Element propElem = new Element(prop);
+      propElem.addContent(object.getProperty(prop));
+      root.addContent(propElem);
+    }
+    return root;
+  }
+}
diff --git a/src/main/java/caosdb/server/accessControl/ACMPermissions.java b/src/main/java/caosdb/server/accessControl/ACMPermissions.java
index 40b063f16932c457fe176006c5b7f438a7a2252e..29988106b842fbd2b825899093e102a7448e8951 100644
--- a/src/main/java/caosdb/server/accessControl/ACMPermissions.java
+++ b/src/main/java/caosdb/server/accessControl/ACMPermissions.java
@@ -24,6 +24,7 @@ package caosdb.server.accessControl;
 
 public class ACMPermissions {
 
+  public static final String PERMISSION_ACCESS_SERVER_PROPERTIES = "ACCESS_SERVER_PROPERTIES";
   public static final String PERMISSION_RETRIEVE_SERVERLOGS = "SERVERLOGS:RETRIEVE";
 
   public static final String PERMISSION_RETRIEVE_USER_ROLES(
diff --git a/src/main/java/caosdb/server/accessControl/AnonymousAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/AnonymousAuthenticationToken.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd3f86f61eb66759b3eb7d0c91c29dc23637000b
--- /dev/null
+++ b/src/main/java/caosdb/server/accessControl/AnonymousAuthenticationToken.java
@@ -0,0 +1,53 @@
+/*
+ * ** header v3.0
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2018 Research Group Biomedical Physics,
+ * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * ** end header
+ */
+package caosdb.server.accessControl;
+
+import org.apache.shiro.authc.AuthenticationToken;
+
+public class AnonymousAuthenticationToken implements AuthenticationToken {
+
+  private static final long serialVersionUID = 1424325396819592888L;
+  private static final AnonymousAuthenticationToken INSTANCE = new AnonymousAuthenticationToken();
+  public static final Object PRINCIPAL = new Object();
+
+  private AnonymousAuthenticationToken() {}
+
+  public static AnonymousAuthenticationToken getInstance() {
+    return INSTANCE;
+  }
+
+  @Override
+  public Object getPrincipal() {
+    return PRINCIPAL;
+  }
+
+  @Override
+  public Object getCredentials() {
+    return null;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return obj == this;
+  }
+}
diff --git a/src/main/java/caosdb/server/accessControl/AnonymousRealm.java b/src/main/java/caosdb/server/accessControl/AnonymousRealm.java
new file mode 100644
index 0000000000000000000000000000000000000000..831d45a727c95277c9d64624e136b2a2e120b3b4
--- /dev/null
+++ b/src/main/java/caosdb/server/accessControl/AnonymousRealm.java
@@ -0,0 +1,44 @@
+/*
+ * ** header v3.0
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2018 Research Group Biomedical Physics,
+ * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * ** end header
+ */
+package caosdb.server.accessControl;
+
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
+import org.apache.shiro.realm.AuthenticatingRealm;
+
+public class AnonymousRealm extends AuthenticatingRealm {
+
+  @Override
+  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
+    return new SimpleAuthenticationInfo(token.getPrincipal(), null, getName());
+  }
+
+  public AnonymousRealm() {
+    setAuthenticationTokenClass(AnonymousAuthenticationToken.class);
+    setCredentialsMatcher(new AllowAllCredentialsMatcher());
+    setCachingEnabled(false);
+    setAuthenticationCachingEnabled(false);
+  }
+}
diff --git a/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java b/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java
index 78aeda064ba413328f9e10d40e507e3fe132c441..31d180a452aafad393fe9d1619705e0e2b49dd9f 100644
--- a/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java
+++ b/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java
@@ -36,6 +36,7 @@ import java.util.Collection;
 import java.util.LinkedList;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import org.apache.shiro.authc.AuthenticationToken;
 import org.restlet.data.Cookie;
 import org.restlet.data.CookieSetting;
 
@@ -55,6 +56,9 @@ public class AuthenticationUtils {
   public static final String SESSION_TOKEN_COOKIE = "SessionToken";
   public static final String SESSION_TIMEOUT_COOKIE = "SessionTimeOut";
 
+  public static final AuthenticationToken ANONYMOUS_USER =
+      AnonymousAuthenticationToken.getInstance();
+
   /**
    * Create a cookie for a {@link SelfValidatingAuthenticationToken}. Returns null if the parameter
    * is null or the token is invalid. The cookie will have the httpOnly and secure flags enabled.
diff --git a/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java b/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java
index a166d723654f1089734f42d405027ad297464e7c..5cfa425ac235405a0c861e54c9d97ae8ffab58f5 100644
--- a/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java
+++ b/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java
@@ -26,7 +26,6 @@ import com.google.common.base.Objects;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
-import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authz.AuthorizationInfo;
@@ -98,6 +97,11 @@ public class CaosDBAuthorizingRealm extends AuthorizingRealm {
         return false;
       }
     }
+
+    @Override
+    public int hashCode() {
+      return this.principalCollection.hashCode();
+    }
   }
 
   private static final CaosDBRolePermissionResolver role_permission_resolver =
@@ -116,7 +120,7 @@ public class CaosDBAuthorizingRealm extends AuthorizingRealm {
 
     // find all roles which are associated with this principal in this
     // realm.
-    final Set<String> roles = UserSources.resolve((Principal) principals.getPrimaryPrincipal());
+    final Set<String> roles = UserSources.resolve(principals);
     if (roles != null) {
       authzInfo.setRoles(roles);
 
@@ -139,8 +143,7 @@ public class CaosDBAuthorizingRealm extends AuthorizingRealm {
   }
 
   @Override
-  protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token)
-      throws AuthenticationException {
+  protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) {
     return null;
   }
 }
diff --git a/src/main/java/caosdb/server/accessControl/CaosDBDefaultRealm.java b/src/main/java/caosdb/server/accessControl/CaosDBDefaultRealm.java
index 7eebee4244eb9d59f86ce7a4263503a91ec12c9a..209487b751c0b73b5fd9085827295d5eb2ce831d 100644
--- a/src/main/java/caosdb/server/accessControl/CaosDBDefaultRealm.java
+++ b/src/main/java/caosdb/server/accessControl/CaosDBDefaultRealm.java
@@ -22,7 +22,6 @@
  */
 package caosdb.server.accessControl;
 
-import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
@@ -32,8 +31,7 @@ import org.apache.shiro.realm.AuthenticatingRealm;
 public class CaosDBDefaultRealm extends AuthenticatingRealm {
 
   @Override
-  protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token)
-      throws AuthenticationException {
+  protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) {
     final String realm = ((RealmUsernamePasswordToken) token).getRealm();
     final String username = ((RealmUsernamePasswordToken) token).getUsername();
     final String password = new String(((RealmUsernamePasswordToken) token).getCredentials());
@@ -50,7 +48,6 @@ public class CaosDBDefaultRealm extends AuthenticatingRealm {
 
     setCachingEnabled(false);
     setAuthenticationCachingEnabled(false);
-    // setAuthorizationCachingEnabled(false);
     setAuthenticationTokenClass(RealmUsernamePasswordToken.class);
   }
 }
diff --git a/src/main/java/caosdb/server/accessControl/SessionTokenRealm.java b/src/main/java/caosdb/server/accessControl/SessionTokenRealm.java
index 95c3642ddbac498be414b3293b8161beb580d4a5..6ee72d0295153051e5ad31a6fd0fa092ab53d6e3 100644
--- a/src/main/java/caosdb/server/accessControl/SessionTokenRealm.java
+++ b/src/main/java/caosdb/server/accessControl/SessionTokenRealm.java
@@ -22,7 +22,6 @@
  */
 package caosdb.server.accessControl;
 
-import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
@@ -32,18 +31,13 @@ import org.apache.shiro.realm.AuthenticatingRealm;
 public class SessionTokenRealm extends AuthenticatingRealm {
 
   @Override
-  protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token)
-      throws AuthenticationException {
-    try {
+  protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) {
 
-      final SelfValidatingAuthenticationToken sessionToken =
-          (SelfValidatingAuthenticationToken) token;
+    final SelfValidatingAuthenticationToken sessionToken =
+        (SelfValidatingAuthenticationToken) token;
 
-      if (sessionToken.isValid()) {
-        return new SimpleAuthenticationInfo(sessionToken.getPrincipal(), null, getName());
-      }
-    } catch (final Exception e) {
-      e.printStackTrace();
+    if (sessionToken.isValid()) {
+      return new SimpleAuthenticationInfo(sessionToken.getPrincipal(), null, getName());
     }
     return null;
   }
@@ -53,6 +47,5 @@ public class SessionTokenRealm extends AuthenticatingRealm {
     setCredentialsMatcher(new AllowAllCredentialsMatcher());
     setCachingEnabled(false);
     setAuthenticationCachingEnabled(false);
-    // setAuthorizationCachingEnabled(false);
   }
 }
diff --git a/src/main/java/caosdb/server/accessControl/UserSources.java b/src/main/java/caosdb/server/accessControl/UserSources.java
index 55b76c4653f7a7339b33bf98cd5f13c7fc6e574a..32b851e8a69f9382c589ceabdafc419bcaaf2c47 100644
--- a/src/main/java/caosdb/server/accessControl/UserSources.java
+++ b/src/main/java/caosdb/server/accessControl/UserSources.java
@@ -34,11 +34,13 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Set;
 import java.util.logging.LogManager;
 import java.util.logging.Logger;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.config.Ini;
+import org.apache.shiro.subject.PrincipalCollection;
 
 public class UserSources extends HashMap<String, UserSource> {
 
@@ -118,6 +120,13 @@ public class UserSources extends HashMap<String, UserSource> {
     }
   }
 
+  /**
+   * Return the roles of a given user.
+   *
+   * @param realm
+   * @param username
+   * @return
+   */
   public static Set<String> resolve(String realm, final String username) {
 
     if (realm == null) {
@@ -158,8 +167,16 @@ public class UserSources extends HashMap<String, UserSource> {
     return instance.map.getSectionProperty(Ini.DEFAULT_SECTION_NAME, KEY_DEAULT_REALM);
   }
 
-  public static Set<String> resolve(final Principal p) {
-    return resolve(p.getRealm(), p.getUsername());
+  public static Set<String> resolve(final PrincipalCollection principals) {
+    if (principals.getPrimaryPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal()) {
+      // anymous has one role
+      Set<String> roles = new HashSet<>();
+      roles.add("anonymous");
+      return roles;
+    }
+
+    Principal primaryPrincipal = (Principal) principals.getPrimaryPrincipal();
+    return resolve(primaryPrincipal.getRealm(), primaryPrincipal.getUsername());
   }
 
   public static boolean isRoleExisting(final String role) {
diff --git a/src/main/java/caosdb/server/database/BackendTransaction.java b/src/main/java/caosdb/server/database/BackendTransaction.java
index a551d5b184ef9c35045697f6f36196665cf648c0..1d5d5c2e68274e664c392a24a901aa4bcd65623b 100644
--- a/src/main/java/caosdb/server/database/BackendTransaction.java
+++ b/src/main/java/caosdb/server/database/BackendTransaction.java
@@ -34,6 +34,7 @@ import caosdb.server.database.backend.implementation.MySQL.MySQLGetFileRecordByP
 import caosdb.server.database.backend.implementation.MySQL.MySQLGetIDByName;
 import caosdb.server.database.backend.implementation.MySQL.MySQLGetInfo;
 import caosdb.server.database.backend.implementation.MySQL.MySQLGetUpdateableChecksums;
+import caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityDatatype;
 import caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityProperties;
 import caosdb.server.database.backend.implementation.MySQL.MySQLInsertLinCon;
 import caosdb.server.database.backend.implementation.MySQL.MySQLInsertLogRecord;
@@ -87,6 +88,7 @@ import caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl;
 import caosdb.server.database.backend.interfaces.GetIDByNameImpl;
 import caosdb.server.database.backend.interfaces.GetInfoImpl;
 import caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl;
+import caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl;
 import caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl;
 import caosdb.server.database.backend.interfaces.InsertLinConImpl;
 import caosdb.server.database.backend.interfaces.InsertLogRecordImpl;
@@ -131,13 +133,11 @@ public abstract class BackendTransaction implements Undoable {
   BackendTransaction parent = null;
   private static HashMap<
           Class<? extends BackendTransactionImpl>, Class<? extends BackendTransactionImpl>>
-      impl =
-          new HashMap<
-              Class<? extends BackendTransactionImpl>, Class<? extends BackendTransactionImpl>>();
+      impl = new HashMap<>();
 
-  protected abstract void execute() throws TransactionException;
+  protected abstract void execute();
 
-  final void executeTransaction() throws TransactionException {
+  final void executeTransaction() {
     final long t1 = System.currentTimeMillis();
     execute();
     final long t2 = System.currentTimeMillis();
@@ -194,10 +194,11 @@ public abstract class BackendTransaction implements Undoable {
       setImpl(SetQueryTemplateDefinitionImpl.class, MySQLSetQueryTemplateDefinition.class);
       setImpl(
           RetrieveQueryTemplateDefinitionImpl.class, MySQLRetrieveQueryTemplateDefinition.class);
+      setImpl(InsertEntityDatatypeImpl.class, MySQLInsertEntityDatatype.class);
     }
   }
 
-  protected <K extends BackendTransaction> K execute(final K t) throws TransactionException {
+  protected <K extends BackendTransaction> K execute(final K t) {
     assert t != this;
     this.undoHandler.append(t);
     t.setAccess(this.access);
@@ -219,8 +220,7 @@ public abstract class BackendTransaction implements Undoable {
   }
 
   @SuppressWarnings("unchecked")
-  protected <T extends BackendTransactionImpl> T getImplementation(final Class<T> clz)
-      throws TransactionException {
+  protected <T extends BackendTransactionImpl> T getImplementation(final Class<T> clz) {
     init();
     try {
       final T ret = (T) impl.get(clz).getConstructor(Access.class).newInstance(this.access);
diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2682e80b1997b53496e3ac2f8e6147726fb77c9
--- /dev/null
+++ b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java
@@ -0,0 +1,52 @@
+package caosdb.server.database.backend.implementation.MySQL;
+
+import caosdb.server.database.access.Access;
+import caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl;
+import caosdb.server.database.exceptions.IntegrityException;
+import caosdb.server.database.exceptions.TransactionException;
+import caosdb.server.database.proto.SparseEntity;
+import java.sql.PreparedStatement;
+import java.sql.SQLIntegrityConstraintViolationException;
+
+public class MySQLInsertEntityDatatype extends MySQLTransaction
+    implements InsertEntityDatatypeImpl {
+
+  public MySQLInsertEntityDatatype(Access access) {
+    super(access);
+  }
+
+  public static final String STMT_INSERT_ENTITY_DATATYPE =
+      "INSERT INTO data_type (domain_id, entity_id, property_id, datatype) SELECT 0, 0, ?, ( SELECT id from entities where name = ? LIMIT 1);";
+  public static final String STMT_INSERT_ENTITY_COLLECTION =
+      "INSERT INTO collection_type (domain_id, entity_id, property_id, collection) SELECT 0, 0, ?, ?;";
+
+  @Override
+  public void execute(final SparseEntity entity) {
+    try {
+      final PreparedStatement insertEntityDatatypeStmt =
+          prepareStatement(STMT_INSERT_ENTITY_DATATYPE);
+
+      insertEntityDatatypeStmt.setInt(1, entity.id);
+      insertEntityDatatypeStmt.setString(2, entity.datatype);
+
+      insertEntityDatatypeStmt.execute();
+
+      if (entity.collection != null) {
+        final PreparedStatement insertEntityCollectionStmt =
+            prepareStatement(STMT_INSERT_ENTITY_COLLECTION);
+
+        insertEntityCollectionStmt.setInt(1, entity.id);
+        insertEntityCollectionStmt.setString(2, entity.collection);
+
+        insertEntityCollectionStmt.execute();
+      }
+
+    } catch (final SQLIntegrityConstraintViolationException exc) {
+      throw new IntegrityException(exc);
+    } catch (final TransactionException exc) {
+      throw exc;
+    } catch (final Exception exc) {
+      throw new TransactionException(exc);
+    }
+  }
+}
diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java
index dbe3893945ae09cadfda0657f9d22d02bd6a9371..4ad9f5b6a3cc3e51c05bc83bbc9332807b79484d 100644
--- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java
+++ b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java
@@ -38,12 +38,12 @@ public class MySQLInsertSparseEntity extends MySQLTransaction implements InsertS
     super(access);
   }
 
-  public static final String STMT_INSERT_SPARSE_ENTITY = "call insertEntity(?,?,?,?,?,?)";
+  public static final String STMT_INSERT_SPARSE_ENTITY = "call insertEntity(?,?,?,?)";
   public static final String STMT_INSERT_FILE_PROPERTIES =
       "INSERT INTO files (file_id, hash, size, path) VALUES (?, unhex(?), ?, ?);";
 
   @Override
-  public void execute(final SparseEntity entity) throws TransactionException {
+  public void execute(final SparseEntity entity) {
     try {
       final PreparedStatement insertEntityStmt = prepareStatement(STMT_INSERT_SPARSE_ENTITY);
       final PreparedStatement insertFilePropsStmt = prepareStatement(STMT_INSERT_FILE_PROPERTIES);
@@ -51,15 +51,14 @@ public class MySQLInsertSparseEntity extends MySQLTransaction implements InsertS
       insertEntityStmt.setString(1, entity.name);
       insertEntityStmt.setString(2, entity.description);
       insertEntityStmt.setString(3, entity.role);
-      insertEntityStmt.setString(4, entity.datatype);
-      insertEntityStmt.setString(5, entity.collection);
-      insertEntityStmt.setString(6, entity.acl);
+      insertEntityStmt.setString(4, entity.acl);
 
-      final ResultSet rs = insertEntityStmt.executeQuery();
-      if (rs.next()) {
-        entity.id = rs.getInt("EntityID");
-      } else {
-        throw new TransactionException("Didn't get new EntityID back.");
+      try (final ResultSet rs = insertEntityStmt.executeQuery()) {
+        if (rs.next()) {
+          entity.id = rs.getInt("EntityID");
+        } else {
+          throw new TransactionException("Didn't get new EntityID back.");
+        }
       }
 
       if (entity.filePath != null) {
diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java b/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f6f7c859281344997e1c781e9a56aafa5d03fc4
--- /dev/null
+++ b/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java
@@ -0,0 +1,8 @@
+package caosdb.server.database.backend.interfaces;
+
+import caosdb.server.database.proto.SparseEntity;
+import caosdb.server.utils.Undoable;
+
+public interface InsertEntityDatatypeImpl extends BackendTransactionImpl, Undoable {
+  public abstract void execute(SparseEntity entity);
+}
diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java b/src/main/java/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java
index 7ba147058b8c4675d58b66a5c11b7dd66311cabf..8ad9a9f7ac0608c4e1e51ba4783a985d0e20d985 100644
--- a/src/main/java/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java
+++ b/src/main/java/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java
@@ -22,11 +22,10 @@
  */
 package caosdb.server.database.backend.interfaces;
 
-import caosdb.server.database.exceptions.TransactionException;
 import caosdb.server.database.proto.SparseEntity;
 import caosdb.server.utils.Undoable;
 
 public interface InsertSparseEntityImpl extends BackendTransactionImpl, Undoable {
 
-  public abstract void execute(SparseEntity entity) throws TransactionException;
+  public abstract void execute(SparseEntity entity);
 }
diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertEntity.java b/src/main/java/caosdb/server/database/backend/transaction/InsertEntity.java
index 65611a4193e8bb494666fb91c3a07a59b4aabd99..e258504908b44c8054a56315fa26e8dacae8b023 100644
--- a/src/main/java/caosdb/server/database/backend/transaction/InsertEntity.java
+++ b/src/main/java/caosdb/server/database/backend/transaction/InsertEntity.java
@@ -23,7 +23,6 @@
 package caosdb.server.database.backend.transaction;
 
 import caosdb.server.database.BackendTransaction;
-import caosdb.server.database.exceptions.TransactionException;
 import caosdb.server.entity.EntityInterface;
 import caosdb.server.entity.container.TransactionContainer;
 import caosdb.server.utils.EntityStatus;
@@ -37,12 +36,17 @@ public class InsertEntity extends BackendTransaction {
   }
 
   @Override
-  public void execute() throws TransactionException {
+  public void execute() {
     for (final EntityInterface newEntity : this.container) {
       if (newEntity.getEntityStatus() == EntityStatus.QUALIFIED) {
         execute(new InsertSparseEntity(newEntity));
       }
     }
+    for (final EntityInterface newEntity : this.container) {
+      if (newEntity.getEntityStatus() == EntityStatus.QUALIFIED && newEntity.hasDatatype()) {
+        execute(new InsertEntityDatatype(newEntity));
+      }
+    }
     for (final EntityInterface newEntity : this.container) {
       if (newEntity.getEntityStatus() == EntityStatus.QUALIFIED) {
         if (newEntity.getQueryTemplateDefinition() != null) {
@@ -51,7 +55,6 @@ public class InsertEntity extends BackendTransaction {
         if (newEntity.hasFileProperties()) {
           execute(new InsertFile(newEntity));
         }
-        // execute(new InsertEntityValue(newEntity));
         execute(new InsertEntityProperties(newEntity));
         execute(new InsertParents(newEntity));
 
diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertEntityDatatype.java b/src/main/java/caosdb/server/database/backend/transaction/InsertEntityDatatype.java
new file mode 100644
index 0000000000000000000000000000000000000000..39c46583cc277eb81128d9fae22d97e296d8bbc1
--- /dev/null
+++ b/src/main/java/caosdb/server/database/backend/transaction/InsertEntityDatatype.java
@@ -0,0 +1,36 @@
+package caosdb.server.database.backend.transaction;
+
+import static caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION;
+
+import caosdb.server.database.BackendTransaction;
+import caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl;
+import caosdb.server.database.exceptions.IntegrityException;
+import caosdb.server.database.proto.SparseEntity;
+import caosdb.server.entity.EntityInterface;
+import caosdb.server.utils.EntityStatus;
+
+public class InsertEntityDatatype extends BackendTransaction {
+
+  private final EntityInterface entity;
+
+  public InsertEntityDatatype(final EntityInterface entity) {
+    this.entity = entity;
+  }
+
+  @Override
+  public void execute() {
+    final InsertEntityDatatypeImpl t = getImplementation(InsertEntityDatatypeImpl.class);
+
+    final SparseEntity e = this.entity.getSparseEntity();
+
+    try {
+      t.execute(e);
+    } catch (final IntegrityException exc) {
+      this.entity.addError(ERROR_INTEGRITY_VIOLATION);
+      this.entity.setEntityStatus(EntityStatus.CORRUPT);
+      throw exc;
+    }
+
+    this.entity.setId(e.id);
+  }
+}
diff --git a/src/main/java/caosdb/server/entity/FileProperties.java b/src/main/java/caosdb/server/entity/FileProperties.java
index 7263b9b2b5e14f51988fa13dd969cf47f941478c..fbf8031f56566ea5a6df263d97611812bab113d0 100644
--- a/src/main/java/caosdb/server/entity/FileProperties.java
+++ b/src/main/java/caosdb/server/entity/FileProperties.java
@@ -216,8 +216,7 @@ public class FileProperties {
     };
   }
 
-  private static Undoable delete(final File file)
-      throws IOException, InterruptedException {
+  private static Undoable delete(final File file) throws IOException, InterruptedException {
     if (file.getAbsolutePath().startsWith(FileSystem.getBasepath())) {
       final Undoable d;
       final File parent = file.getParentFile();
diff --git a/src/main/java/caosdb/server/permissions/EntityACL.java b/src/main/java/caosdb/server/permissions/EntityACL.java
index d389a2163aeb46c013f8845abda104779a67d8eb..79008947823e9625283c03e1dd539328a58fef7f 100644
--- a/src/main/java/caosdb/server/permissions/EntityACL.java
+++ b/src/main/java/caosdb/server/permissions/EntityACL.java
@@ -25,6 +25,7 @@ package caosdb.server.permissions;
 import static caosdb.server.permissions.Role.OTHER_ROLE;
 import static caosdb.server.permissions.Role.OWNER_ROLE;
 
+import caosdb.server.accessControl.AuthenticationUtils;
 import caosdb.server.accessControl.Principal;
 import caosdb.server.database.exceptions.TransactionException;
 import java.util.ArrayList;
@@ -74,6 +75,9 @@ public class EntityACL {
   }
 
   public static final EntityACL getOwnerACLFor(final Subject subject) {
+    if (subject.getPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal()) {
+      return new EntityACLFactory().create();
+    }
     return getOwnerACLFor((Principal) subject.getPrincipal());
   }
 
diff --git a/src/main/java/caosdb/server/query/POV.java b/src/main/java/caosdb/server/query/POV.java
index 51ff02c9bb5bea648dd88dd671fd74bef609b364..a24aee4e7153e2b84b3e122b2a848fb79fe16367 100644
--- a/src/main/java/caosdb/server/query/POV.java
+++ b/src/main/java/caosdb/server/query/POV.java
@@ -329,7 +329,7 @@ public class POV implements EntityFilterInterface {
         query.getConnection().prepareCall("call initPOVRefidsTable(?,?)")) {
       // stmt = this.connection.prepareCall("call initPOV(?,?,?,?,?)");
       // initPOVRefidsTable(in vInt INT, in vText VARCHAR(255))
-      if (this.vInt != null) {
+      if (this.vInt != null && this.vInt > 0) {
         stmt.setInt(1, this.vInt);
       } else {
         stmt.setNull(1, Types.INTEGER);
diff --git a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java
index e390d3c55576e774a78e89f17de73ed950b78cf4..709825c8176e0e759249efb41c5e8fd075829959 100644
--- a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java
+++ b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java
@@ -26,7 +26,9 @@ import static caosdb.server.utils.Utils.isNonNullInteger;
 import static java.net.URLDecoder.decode;
 
 import caosdb.server.CaosDBException;
+import caosdb.server.accessControl.AuthenticationUtils;
 import caosdb.server.accessControl.Principal;
+import caosdb.server.accessControl.UserSources;
 import caosdb.server.database.backend.implementation.MySQL.ConnectionException;
 import caosdb.server.entity.Message;
 import caosdb.server.utils.ServerMessages;
@@ -36,6 +38,7 @@ import java.io.UnsupportedEncodingException;
 import java.security.NoSuchAlgorithmException;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.NoSuchElementException;
@@ -73,7 +76,7 @@ public abstract class AbstractCaosDBServerResource extends ServerResource {
   private Long timestamp = null;
   private static final XMLParser xmlparser = new XMLParser();
   protected String sRID = null;
-  protected String cRID = null;
+  private String cRID = null;
   private String[] requestedItems = null;
   private ArrayList<Integer> requestedIDs = new ArrayList<Integer>();
   private ArrayList<String> requestedNames = new ArrayList<String>();
@@ -108,7 +111,7 @@ public abstract class AbstractCaosDBServerResource extends ServerResource {
 
     final Series<Header> headers = getRequest().getHeaders();
 
-    this.cRID = headers.getFirstValue("crequestid");
+    this.setCRID(headers.getFirstValue("crequestid"));
 
     String specifier = (String) getRequestAttributes().get("specifier");
     if (specifier != null && !specifier.equals("")) {
@@ -156,19 +159,68 @@ public abstract class AbstractCaosDBServerResource extends ServerResource {
   protected Element generateRootElement() {
     final Element retRoot = new Element("Response");
 
-    if (getUser() != null && getUser().isAuthenticated()) {
-      retRoot.setAttribute("username", ((Principal) getUser().getPrincipal()).getUsername());
-      retRoot.setAttribute("realm", ((Principal) getUser().getPrincipal()).getRealm());
-    }
+    addUserInfo(retRoot, getUser());
     retRoot.setAttribute("srid", getSRID());
-    if (this.cRID != null) {
-      retRoot.setAttribute("crid", this.cRID);
+    if (this.getCRID() != null) {
+      retRoot.setAttribute("crid", this.getCRID());
     }
     retRoot.setAttribute("timestamp", getTimestamp().toString());
     retRoot.setAttribute("baseuri", getRootRef().toString());
     return retRoot;
   }
 
+  /**
+   * Add the user info to the Response Element.
+   *
+   * @param retRoot
+   * @param user
+   */
+  private void addUserInfo(Element retRoot, Subject user) {
+
+    if (user != null && user.isAuthenticated()) {
+      Element userInfo = new Element("UserInfo");
+      if (!user.getPrincipal().equals(AuthenticationUtils.ANONYMOUS_USER.getPrincipal())) {
+        // TODO: deprecated
+        addNameAndRealm(retRoot, user);
+
+        // this is the new, correct way
+        addNameAndRealm(userInfo, user);
+      }
+
+      addRoles(userInfo, user);
+      retRoot.addContent(userInfo);
+    }
+  }
+
+  /**
+   * Add all roles of the current user to the user info, like this:
+   * `<UserInfo><Roles><Role>role1</Role><Role>role2</Role>...</Roles></UserInfo>`
+   *
+   * @param userInfo
+   * @param user
+   */
+  private void addRoles(Element userInfo, Subject user) {
+    Collection<String> roles = UserSources.resolve(user.getPrincipals());
+    if (roles == null) return;
+    Element rs = new Element("Roles");
+    for (String role : roles) {
+      Element r = new Element("Role");
+      r.addContent(role);
+      rs.addContent(r);
+    }
+    userInfo.addContent(rs);
+  }
+
+  /**
+   * Add the username and the realm of the current user to the user info (as attributes).
+   *
+   * @param userInfo
+   */
+  private void addNameAndRealm(Element userInfo, Subject user) {
+    userInfo.setAttribute("username", ((Principal) user.getPrincipal()).getUsername());
+    userInfo.setAttribute("realm", ((Principal) user.getPrincipal()).getRealm());
+  }
+
   @Get
   public Representation httpGet() {
     try {
@@ -264,19 +316,29 @@ public abstract class AbstractCaosDBServerResource extends ServerResource {
     return new JdomRepresentation(doc, MediaType.TEXT_XML, "  ", getReference(), getXSLScript());
   }
 
-  protected JdomRepresentation error(final Message m, final Status status) {
+  protected Representation error(final Message m, final Status status) {
     final Document doc = new Document();
     final Element root = generateRootElement();
     root.addContent(m.toElement().setName("Error"));
     doc.setRootElement(root);
+    return error(
+        new JdomRepresentation(doc, MediaType.TEXT_XML, "  ", getReference(), getXSLScript()),
+        status);
+  }
+
+  protected Representation error(Representation entity, Status status) {
     getResponse().setStatus(status);
-    return new JdomRepresentation(doc, MediaType.TEXT_XML, "  ", getReference(), getXSLScript());
+    return entity;
   }
 
-  protected JdomRepresentation error(final Message m) {
+  protected Representation error(final Message m) {
     return error(m, Status.SERVER_ERROR_INTERNAL);
   }
 
+  protected Representation error(final Status status) {
+    return error((Representation) null, status);
+  }
+
   protected JdomRepresentation warning(final Message m) {
     final Document doc = new Document();
     final Element root = generateRootElement();
@@ -285,19 +347,19 @@ public abstract class AbstractCaosDBServerResource extends ServerResource {
     return new JdomRepresentation(doc, MediaType.TEXT_XML, "  ", getReference(), getXSLScript());
   }
 
-  protected JdomRepresentation noWellFormedNess() {
+  protected Representation noWellFormedNess() {
     return error(ServerMessages.REQUEST_BODY_NOT_WELLFORMED);
   }
 
-  protected JdomRepresentation emptyEntity() {
+  protected Representation emptyEntity() {
     return error(ServerMessages.REQUEST_BODY_EMPTY);
   }
 
-  protected JdomRepresentation connectionFailed() {
+  protected Representation connectionFailed() {
     return error(ServerMessages.CANNOT_CONNECT_TO_DATABASE);
   }
 
-  public JdomRepresentation handleThrowable(final Throwable t) {
+  public Representation handleThrowable(final Throwable t) {
     try {
       getRequest().getAttributes().put("THROWN", t);
       throw t;
@@ -351,6 +413,14 @@ public abstract class AbstractCaosDBServerResource extends ServerResource {
     return root;
   }
 
+  public String getCRID() {
+    return cRID;
+  }
+
+  public void setCRID(String cRID) {
+    this.cRID = cRID;
+  }
+
   public static class XMLParser {
     private final LinkedList<SAXBuilder> pool = new LinkedList<SAXBuilder>();
     private final int max = 25;
diff --git a/src/main/java/caosdb/server/resource/ScriptingResource.java b/src/main/java/caosdb/server/resource/ScriptingResource.java
index 4687b2c5ad241baddc6662c5fb043ac955839ff6..b5a82ef33d9a50da0568defd614d6c86048c8cd9 100644
--- a/src/main/java/caosdb/server/resource/ScriptingResource.java
+++ b/src/main/java/caosdb/server/resource/ScriptingResource.java
@@ -96,10 +96,12 @@ public class ScriptingResource extends AbstractCaosDBServerResource {
   private void deleteTmpFiles() {
     for (FileProperties p : deleteFiles) {
       try {
-      p.getFile().delete();
+        p.getFile().delete();
       } catch (Exception t) {
         if (getLogger().isLoggable(Level.WARNING)) {
-          getLogger().warning("Could not delete tmp file: " + p.getPath() + "\nException: " + t.toString());
+          getLogger()
+              .warning(
+                  "Could not delete tmp file: " + p.getPath() + "\nException: " + t.toString());
         }
       }
     }
diff --git a/src/main/java/caosdb/server/resource/ServerPropertiesResource.java b/src/main/java/caosdb/server/resource/ServerPropertiesResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b878e3338a9d0b0c74704acb412ac92ceb1f0c4
--- /dev/null
+++ b/src/main/java/caosdb/server/resource/ServerPropertiesResource.java
@@ -0,0 +1,42 @@
+package caosdb.server.resource;
+
+import caosdb.server.CaosDBServer;
+import caosdb.server.ServerPropertiesSerializer;
+import caosdb.server.accessControl.ACMPermissions;
+import org.restlet.data.Form;
+import org.restlet.data.Parameter;
+import org.restlet.data.Status;
+import org.restlet.representation.Representation;
+
+public class ServerPropertiesResource extends AbstractCaosDBServerResource {
+
+  @Override
+  protected void doInit() {
+    super.doInit();
+    setXSLScript("xsl/server_properties.xsl");
+  }
+
+  @Override
+  protected Representation httpGetInChildClass() {
+    if (CaosDBServer.isDebugMode()) {
+      getUser().checkPermission(ACMPermissions.PERMISSION_ACCESS_SERVER_PROPERTIES);
+      return super.ok(
+          new ServerPropertiesSerializer().serialize(CaosDBServer.getServerProperties()));
+    }
+    return error(Status.CLIENT_ERROR_NOT_FOUND);
+  }
+
+  @Override
+  protected Representation httpPostInChildClass(Representation entity) {
+    if (CaosDBServer.isDebugMode()) {
+      getUser().checkPermission(ACMPermissions.PERMISSION_ACCESS_SERVER_PROPERTIES);
+      Form form = new Form(entity);
+      for (Parameter param : form) {
+        CaosDBServer.setProperty(param.getName(), param.getValue());
+      }
+      return super.ok(
+          new ServerPropertiesSerializer().serialize(CaosDBServer.getServerProperties()));
+    }
+    return error(Status.CLIENT_ERROR_NOT_FOUND);
+  }
+}
diff --git a/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java b/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java
index d239d570db89aa6c86b015a70474fb36c0080dcb..903ef0d5aca9a91eaeaff3693b7f77ef51e6cc46 100644
--- a/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java
+++ b/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java
@@ -58,8 +58,8 @@ public class TestCaseFileSystemResource extends FileSystemResource {
       retRoot.setAttribute("realm", ((Principal) getUser().getPrincipal()).getRealm());
     }
     retRoot.setAttribute("srid", getSRID());
-    if (this.cRID != null) {
-      retRoot.setAttribute("crid", this.cRID);
+    if (this.getCRID() != null) {
+      retRoot.setAttribute("crid", this.getCRID());
     }
     retRoot.setAttribute("timestamp", getTimestamp().toString());
     retRoot.setAttribute("baseuri", getRootRef().toString() + "/TestCase/");
diff --git a/src/main/java/caosdb/server/resource/TestCaseResource.java b/src/main/java/caosdb/server/resource/TestCaseResource.java
index ed7e546147bd717ebe92821e39abe4e256b470fb..e8aef1f00e57335185b7b204c8de081570e6e188 100644
--- a/src/main/java/caosdb/server/resource/TestCaseResource.java
+++ b/src/main/java/caosdb/server/resource/TestCaseResource.java
@@ -84,8 +84,8 @@ public class TestCaseResource extends AbstractCaosDBServerResource {
     retRoot.setAttribute("username", "TestUser");
     retRoot.setAttribute("realm", "PAM");
     retRoot.setAttribute("srid", getSRID());
-    if (this.cRID != null) {
-      retRoot.setAttribute("crid", this.cRID);
+    if (this.getCRID() != null) {
+      retRoot.setAttribute("crid", this.getCRID());
     }
     retRoot.setAttribute("timestamp", getTimestamp().toString());
     retRoot.setAttribute("baseuri", getRootRef().toString() + "/TestCase/");
diff --git a/src/main/java/caosdb/server/scripting/CallerSerializer.java b/src/main/java/caosdb/server/scripting/CallerSerializer.java
index 1bd265650bed0d5de865cc91b29db3327b56174b..1ab96ca0ab1a3f2dfefa14175d8423fea9bd4109 100644
--- a/src/main/java/caosdb/server/scripting/CallerSerializer.java
+++ b/src/main/java/caosdb/server/scripting/CallerSerializer.java
@@ -1,3 +1,25 @@
+/*
+ * ** header v3.0
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2018 Research Group Biomedical Physics,
+ * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * ** end header
+ */
 package caosdb.server.scripting;
 
 import caosdb.server.CaosDBException;
diff --git a/src/main/java/caosdb/server/transaction/Transaction.java b/src/main/java/caosdb/server/transaction/Transaction.java
index 2a7562c146aaca1edabb85127d488ffd2994233e..347e806e059edd124e9efde065c5509de3658c4c 100644
--- a/src/main/java/caosdb/server/transaction/Transaction.java
+++ b/src/main/java/caosdb/server/transaction/Transaction.java
@@ -23,6 +23,7 @@
 package caosdb.server.transaction;
 
 import caosdb.datetime.UTCDateTime;
+import caosdb.server.accessControl.AuthenticationUtils;
 import caosdb.server.accessControl.Principal;
 import caosdb.server.database.Database;
 import caosdb.server.database.DatabaseMonitor;
@@ -222,13 +223,17 @@ public abstract class Transaction<C extends TransactionContainer> extends Abstra
   // TODO move to post-transaction job
   private void writeHistory() throws TransactionException, Message {
     if (logHistory()) {
+      String realm =
+          getTransactor().getPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal()
+              ? ""
+              : ((Principal) getTransactor().getPrincipal()).getRealm();
+      String username =
+          getTransactor().getPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal()
+              ? "anonymous"
+              : ((Principal) getTransactor().getPrincipal()).getUsername();
       Database.execute(
           new InsertTransactionHistory(
-              getContainer(),
-              this.getClass().getSimpleName(),
-              ((Principal) getTransactor().getPrincipal()).getRealm(),
-              ((Principal) getTransactor().getPrincipal()).getUsername(),
-              getTimestamp()),
+              getContainer(), this.getClass().getSimpleName(), realm, username, getTimestamp()),
           getAccess());
     }
   }
diff --git a/src/main/java/caosdb/server/utils/Serializer.java b/src/main/java/caosdb/server/utils/Serializer.java
index 5508e99388a9e4191fd524ccbfc3e30007f6759a..26cd970c54d2bc4efcb7742ab9405a717e3ef112 100644
--- a/src/main/java/caosdb/server/utils/Serializer.java
+++ b/src/main/java/caosdb/server/utils/Serializer.java
@@ -1,3 +1,25 @@
+/*
+ * ** header v3.0
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2018 Research Group Biomedical Physics,
+ * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * ** end header
+ */
 package caosdb.server.utils;
 
 public interface Serializer<T, S> {
diff --git a/src/test/java/caosdb/datetime/DateTimeTest.java b/src/test/java/caosdb/datetime/DateTimeTest.java
index 2c66bcb14729514c7812ab6a64b388df652cff63..6366dccd5910c972e68201e7314275825f0f84b6 100644
--- a/src/test/java/caosdb/datetime/DateTimeTest.java
+++ b/src/test/java/caosdb/datetime/DateTimeTest.java
@@ -408,7 +408,7 @@ public class DateTimeTest {
   public void testUTCRange() {
     Interval d = (Interval) DateTimeFactory2.valueOf("9999-01-01T23:59:59UTC");
     assertTrue(d instanceof UTCDateTime);
-    assertEquals("253370851225UTC", d.getILB_NF1());
+    assertEquals("253370851226UTC", d.getILB_NF1());
     Interval d2 = UTCDateTime.UTCSeconds(253370851225L, null);
     assertTrue(d instanceof UTCDateTime);
     assertEquals("253370851225UTC", d2.getILB_NF1());
@@ -418,7 +418,7 @@ public class DateTimeTest {
 
     d = (Interval) DateTimeFactory2.valueOf("9999-01-01T23:59:59.999999999UTC");
     assertTrue(d instanceof UTCDateTime);
-    assertEquals("253370851225UTC999999999", d.getILB_NF1());
+    assertEquals("253370851226UTC999999999", d.getILB_NF1());
     d2 = UTCDateTime.UTCSeconds(253370851225L, 999999999);
     assertTrue(d instanceof UTCDateTime);
     assertEquals("253370851225UTC999999999", d2.getILB_NF1());
diff --git a/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java b/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..57031f088d9ca9f939b9772ae8d613df914208c4
--- /dev/null
+++ b/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java
@@ -0,0 +1,73 @@
+package caosdb.server.resource;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import caosdb.server.CaosDBException;
+import caosdb.server.accessControl.AnonymousAuthenticationToken;
+import caosdb.server.accessControl.AnonymousRealm;
+import caosdb.server.database.backend.implementation.MySQL.ConnectionException;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.sql.SQLException;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.subject.support.DelegatingSubject;
+import org.jdom2.Element;
+import org.junit.Test;
+import org.restlet.data.Reference;
+import org.restlet.representation.Representation;
+
+public class TestAbstractCaosDBServerResource {
+
+  @Test
+  public void testReponseRootElement() {
+    final Subject user = new DelegatingSubject(new DefaultSecurityManager(new AnonymousRealm()));
+    user.login(AnonymousAuthenticationToken.getInstance());
+    AbstractCaosDBServerResource s =
+        new AbstractCaosDBServerResource() {
+
+          @Override
+          protected Representation httpGetInChildClass()
+              throws ConnectionException, IOException, SQLException, CaosDBException,
+                  NoSuchAlgorithmException, Exception {
+            // TODO Auto-generated method stub
+            return null;
+          }
+
+          @Override
+          public String getSRID() {
+            return "TEST-SRID";
+          }
+
+          @Override
+          public String getCRID() {
+            return "TEST-CRID";
+          }
+
+          @Override
+          public Long getTimestamp() {
+            return 0L;
+          }
+
+          @Override
+          public Reference getRootRef() {
+            return new Reference("https://example.com/root/");
+          }
+
+          @Override
+          public Subject getUser() {
+            // TODO Auto-generated method stub
+            return user;
+          }
+        };
+    Element response = s.generateRootElement();
+    assertNotNull(response);
+    assertEquals("TEST-SRID", response.getAttribute("srid").getValue());
+    assertEquals("TEST-CRID", response.getAttribute("crid").getValue());
+    assertEquals("0", response.getAttribute("timestamp").getValue());
+    assertEquals("https://example.com/root/", response.getAttributeValue("baseuri"));
+    Element userInfo = response.getChild("UserInfo");
+    assertNotNull(userInfo);
+  }
+}