diff --git a/scripting/bin/administration/diagnostics.py b/scripting/bin/administration/diagnostics.py
index a4df74001d79eb1d7b078de23a77a8d8f9631a0b..b7830df8e94acc1de65685af6f471267e2211a43 100755
--- a/scripting/bin/administration/diagnostics.py
+++ b/scripting/bin/administration/diagnostics.py
@@ -40,6 +40,18 @@ TEST_MODULES = [
 ]
 
 
+def get_files():
+    from os import walk
+    from os.path import join
+    result = []
+    for p, dirs, files in walk("."):
+        for f in files:
+            result.append(join(p, f))
+        for d in dirs:
+            result.append(join(p, d))
+    return result
+
+
 def get_option(name, default=None):
     for arg in sys.argv:
         if arg.startswith("--{}=".format(name)):
@@ -106,9 +118,9 @@ def main():
     try:
         import json
     except ImportError:
-        print('{"python_version":"{v}",'
-              '"python_path":["{p}"]}'.format(v=sys.version,
-                                              p='","'.join(sys.path)))
+        print('{{"python_version":"{v}",'
+              '"python_path":["{p}"]}}'.format(v=sys.version,
+                                               p='","'.join(sys.path)))
         raise
 
     try:
@@ -117,6 +129,7 @@ def main():
         diagnostics["python_path"] = sys.path
         diagnostics["call"] = sys.argv
         diagnostics["import"] = test_imports(TEST_MODULES)
+        diagnostics["files"] = get_files()
 
         auth_token = get_auth_token()
         diagnostics["auth_token"] = auth_token
diff --git a/src/main/java/caosdb/server/accessControl/UserSources.java b/src/main/java/caosdb/server/accessControl/UserSources.java
index 2b3019f9655a972267668ba1dc2166bfc8f23a06..be7cd286965963b7fef6372c004d3c5142f77ea9 100644
--- a/src/main/java/caosdb/server/accessControl/UserSources.java
+++ b/src/main/java/caosdb/server/accessControl/UserSources.java
@@ -40,6 +40,31 @@ import org.apache.shiro.config.Ini;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * This singleton class is the primary resource for authenticating users and resolving principals to
+ * roles.
+ *
+ * <p>Key concepts:
+ *
+ * <ul>
+ *   <li>User name: A string which identifies a user uniquely across one realm. Why is this so?
+ *       Because it is possible, that two different people from collaborating work groups with
+ *       similar names have the same user name in their group e.g. "mueller@uni1.de" and
+ *       "mueller@uni2.de" or two people from different user groups use the name "admin". In the
+ *       "mueller" example the domain name of the email is the realm of authentication.
+ *   <li>Realm: A string which uniquely identifies "where a user comes from". It guarantees the
+ *       authentication of a user with a particular user name. Currently the possible realms are
+ *       quite limited. Only "CaosDB" (which is controlled by the internal user source) and "PAM"
+ *       which delegates authentication to the host system via PAM (Pluggable Authentication Module)
+ *       are known and extension is not too easy.
+ *   <li>User Source: An instance which provides the access to a realm where users can be
+ *       authenticated.
+ *   <li>Principal: The combination of realm and user name - hence a system-wide unique identifier
+ *       for users and the primary key to identifying who did what and who is allowed to to do what.
+ * </ul>
+ *
+ * @author Timm Fitschen (t.fitschen@indiscale.com)
+ */
 public class UserSources extends HashMap<String, UserSource> {
 
   public static final String ANONYMOUS_ROLE = "anonymous";
@@ -171,7 +196,7 @@ public class UserSources extends HashMap<String, UserSource> {
   }
 
   public static Set<String> resolve(final Principal principal) {
-    if (AuthenticationUtils.isAnonymous(principal)) {
+    if (AnonymousAuthenticationToken.PRINCIPAL == principal) {
       // anymous has one role
       Set<String> roles = new HashSet<>();
       roles.add(ANONYMOUS_ROLE);