status code refactor and file for generic api messages

Change-Id: Id1e9b3edce30098d13a1655c5dee5f1e2fea89f1
diff --git a/src/main/java/de/ids_mannheim/korap/config/ConfigLoader.java b/src/main/java/de/ids_mannheim/korap/config/ConfigLoader.java
index 2fda630..855417c 100644
--- a/src/main/java/de/ids_mannheim/korap/config/ConfigLoader.java
+++ b/src/main/java/de/ids_mannheim/korap/config/ConfigLoader.java
@@ -44,9 +44,13 @@
     }
 
 
-    public static Properties loadProperties (String name) throws IOException {
+    public static Properties loadProperties (String name){
         Properties p = new Properties();
-        p.load(loadConfigStream(name));
+        try {
+            p.load(loadConfigStream(name));
+        } catch (IOException e) {
+            throw new RuntimeException("Properties from config file '"+name+"' could not be loaded ...");
+        }
         return p;
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/exceptions/EmptyResultException.java b/src/main/java/de/ids_mannheim/korap/exceptions/EmptyResultException.java
index 0a4bb7b..8bf1810 100644
--- a/src/main/java/de/ids_mannheim/korap/exceptions/EmptyResultException.java
+++ b/src/main/java/de/ids_mannheim/korap/exceptions/EmptyResultException.java
@@ -9,12 +9,12 @@
 public class EmptyResultException extends KustvaktException {
 
     public EmptyResultException (String message, String entity) {
-        super(StatusCodes.EMPTY_RESULTS, message, entity);
+        super(StatusCodes.NO_VALUE_FOUND, message, entity);
     }
 
 
     public EmptyResultException (String entity) {
-        super(StatusCodes.EMPTY_RESULTS, "No entity found for id", entity);
+        super(StatusCodes.NO_VALUE_FOUND, "No entity found for id", entity);
     }
 
 }
diff --git a/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java b/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
index 8e4148c..bdbe010 100644
--- a/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
+++ b/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
@@ -47,6 +47,14 @@
         this.userid = String.valueOf(userid);
     }
 
+    public KustvaktException (Object userid, int status,
+                              String entity) {
+        super(StatusCodes.getMessage(status));
+        this.statusCode = status;
+        this.entity = entity;
+        this.userid = String.valueOf(userid);
+    }
+
 
     public KustvaktException (int status, String message, String entity) {
         super(message);
diff --git a/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java b/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
index 14cb52a..66c89b5 100644
--- a/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
+++ b/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
@@ -16,68 +16,37 @@
     /**
      * 100 status codes for standard system errors
      */
-    public static final int EMPTY_RESULTS = 100;
-    public static final int REQUEST_INVALID = 101;
-    //fixme: redundancy?!
+    public static final int DEFAULT_ERROR = 100;
+    public static final int NO_VALUE_FOUND = 101;
     public static final int ENTRY_EXISTS = 102;
-    public static final int STATUS_OK = 103;
-    public static final int UNSUPPORTED_OPERATION = 104;
-    public static final int ILLEGAL_ARGUMENT = 105;
+    public static final int UNSUPPORTED_OPERATION = 103;
+    public static final int ILLEGAL_ARGUMENT = 104;
+    public static final int MISSING_ARGUMENT = 105;
     public static final int CONNECTION_ERROR = 106;
-    public static final int NOTHING_CHANGED = 107;
-    public static final int PARAMETER_VALIDATION_ERROR = 108;
-    public static final int DEFAULT_ERROR = 109;
-    public static final int NOT_SUPPORTED = 110;
-
-    /**
-     * 200 status codes for account/authentication relevant components
-     */
-
-    public static final int ACCOUNT_DEACTIVATED = 200;
-    public static final int ACCOUNT_CONFIRMATION_FAILED = 201;
-    public static final int ALREADY_LOGGED_IN = 202;
-    public static final int EXPIRED = 204;
-    public static final int BAD_CREDENTIALS = 205;
-    @Deprecated // fixme: duplicate to account deactivated
-    public static final int UNCONFIRMED_ACCOUNT = 206;
-    public static final int NAME_EXISTS = 207;
-    public static final int PASSWORD_RESET_FAILED = 208;
-    // fixme: ?!
-    @Deprecated
-    public static final int AUTHENTICATION_DENIED = 209;
-
-    public static final int LOGIN_SUCCESSFUL = 210;
-    public static final int LOGIN_FAILED = 211;
-    public static final int LOGOUT_SUCCESSFUL = 212;
-    public static final int LOGOUT_FAILED = 213;
-
-    public static final int CLIENT_REGISTRATION_FAILURE = 214;
-    public static final int CLIENT_REMOVAL_FAILURE = 215;
-    public static final int CLIENT_AUTHORIZATION_FAILURE = 216;
-
+    public static final int PARAMETER_VALIDATION_ERROR = 107;
+    public static final int NOT_SUPPORTED = 108;
 
     /**
      *  400 status codes for authorization and rewrite functions
      */
 
     // fixme: use unsupported resource and include type in return message
-    public static final int PERMISSION_DENIED = 401;
+    public static final int POLICY_ERROR_DEFAULT = 400;
     public static final int UNSUPPORTED_RESOURCE = 402;
-    public static final int UNSUPPORTED_FOUNDRY = 403;
-    public static final int UNSUPPORTED_CORPUS = 404;
-    public static final int UNSUPPORTED_LAYER = 405;
+    public static final int FAILED_REWRITE = 403;
+    //public static final int UNSUPPORTED_FOUNDRY = 403;
+    //public static final int UNSUPPORTED_CORPUS = 404;
+    //public static final int UNSUPPORTED_LAYER = 405;
     // make a distinction between no and invalid vc?
-    public static final int UNSUPPORTED_COLLECTION = 406;
-    public static final int CORPUS_REWRITE = 407;
-    public static final int FOUNDRY_REWRITE = 408;
-    public static final int FOUNDRY_INJECTION = 409;
-    public static final int MISSING_ARGUMENTS = 410;
-    public static final int MISSING_VIRTUALCOLLECTION = 411;
-    public static final int MISSING_POLICY_TARGET = 412;
-    public static final int MISSING_POLICY_CONDITIONS = 413;
-    public static final int MISSING_POLICY_PERMISSION = 414;
-    public static final int RESOURCE_NOT_FOUND = 415;
-    public static final int ACCESS_DENIED_NO_RESOURCES = 416;
+    //public static final int UNSUPPORTED_COLLECTION = 406;
+    //public static final int CORPUS_REWRITE = 407;
+    //public static final int FOUNDRY_REWRITE = 408;
+    //public static final int FOUNDRY_INJECTION = 409;
+    public static final int MISSING_RESOURCE = 405;
+    public static final int NO_POLICY_TARGET = 406;
+    public static final int NO_POLICY_CONDITION = 407;
+    public static final int NO_POLICY_PERMISSION = 408;
+    public static final int NO_POLICIES = 409;
 
 
     /**
@@ -86,20 +55,62 @@
      */
     // todo: extend according to policy rewrite possible!
     // policy errors
-    public static final int POLICY_ERROR_DEFAULT = 500;
-    public static final int POLICY_CREATE_ERROR = 501;
-    public static final int NO_POLICIES = 502;
+
 
     // database codes
-    public static final int DB_GET_FAILED = 601;
-    public static final int DB_INSERT_FAILED = 602;
-    public static final int DB_DELETE_FAILED = 603;
-    public static final int DB_UPDATE_FAILED = 604;
+    public static final int DB_GET_FAILED = 500;
+    public static final int DB_INSERT_FAILED = 501;
+    public static final int DB_DELETE_FAILED = 502;
+    public static final int DB_UPDATE_FAILED = 503;
 
-    public static final int DB_GET_SUCCESSFUL = 605;
-    public static final int DB_INSERT_SUCCESSFUL = 606;
-    public static final int DB_DELETE_SUCCESSFUL = 607;
-    public static final int DB_UPDATE_SUCCESSFUL = 608;
+    public static final int DB_GET_SUCCESSFUL = 504;
+    public static final int DB_INSERT_SUCCESSFUL = 505;
+    public static final int DB_DELETE_SUCCESSFUL = 506;
+    public static final int DB_UPDATE_SUCCESSFUL = 507;
+
+
+    public static final int ARGUMENT_VALIDATION_FAILURE = 700;
+    // public static final int ARGUMENT_VALIDATION_FAILURE = 701;
+
+
+    /**
+     * 300 status codes for query language and serialization
+     */
+
+    public static final int NO_QUERY = 301;
+
+
+
+    public static final int STATUS_OK = 1000;
+    public static final int NOTHING_CHANGED = 1001;
+    public static final int REQUEST_INVALID = 1002;
+    public static final int ACCESS_DENIED = 1003;
+
+    /**
+     * 2000 status and error codes for service level messages and callbacks
+     */
+
+
+    public static final int ACCOUNT_DEACTIVATED = 2000;
+    public static final int ACCOUNT_CONFIRMATION_FAILED = 2001;
+    public static final int ALREADY_LOGGED_IN = 2002;
+
+    public static final int EXPIRED = 2003;
+    public static final int BAD_CREDENTIALS = 2004;
+    public static final int ACCOUNT_NOT_CONFIRMED = 2005;
+
+    public static final int PASSWORD_RESET_FAILED = 2006;
+
+    public static final int LOGIN_SUCCESSFUL = 2007;
+    public static final int LOGIN_FAILED = 2008;
+    public static final int LOGOUT_SUCCESSFUL = 2009;
+    public static final int LOGOUT_FAILED = 2010;
+
+    public static final int CLIENT_REGISTRATION_FAILURE = 2011;
+    public static final int CLIENT_REMOVAL_FAILURE = 2012;
+    public static final int CLIENT_AUTHORIZATION_FAILURE = 2013;
+
+
 
     // service status codes
     public static final int CREATE_ACCOUNT_SUCCESSFUL = 700;
@@ -112,16 +123,24 @@
     public static final int GET_ACCOUNT_SUCCESSFUL = 706;
     public static final int GET_ACCOUNT_FAILED = 707;
 
-    /**
-     * 300 status codes for query language and serialization
-     */
 
-    public static final int NO_QUERY = 301;
+    private static StatusCodes codes;
 
-
+    private final Properties props;
 
     private StatusCodes() {
+        this.props = ConfigLoader.loadProperties("codes.info");
+    }
 
+
+    public static final String getMessage(int code) {
+        return getCodes().props.getProperty(String.valueOf(code));
+    }
+
+    public static StatusCodes getCodes() {
+            if (codes == null)
+                codes = new StatusCodes();
+        return codes;
     }
 
 }
diff --git a/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java b/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
index 46b0544..a13eeeb 100644
--- a/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
+++ b/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
@@ -204,7 +204,7 @@
             jlog.error("Could not create user account with username: {}",
                     user.getUsername());
             throw new dbException(user.getUsername(), "korap_users",
-                    StatusCodes.NAME_EXISTS, user.getUsername());
+                    StatusCodes.ENTRY_EXISTS, user.getUsername());
         }
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java
index d7e32ee..b6508f5 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java
@@ -41,9 +41,10 @@
             Set resources = ResourceFinder.search(user, Corpus.class);
             ArrayList<KustvaktResource> list = new ArrayList(resources);
 
+            // fixme: throw exception in resourcefinder to indicate if no resource or no permission!
             if (list.isEmpty())
                 throw new KustvaktException(
-                        StatusCodes.ACCESS_DENIED_NO_RESOURCES,
+                        StatusCodes.NO_POLICY_PERMISSION,
                         "Resources could not be loaded for user ",
                         user.getUsername());
 
diff --git a/src/main/java/de/ids_mannheim/korap/resources/Permissions.java b/src/main/java/de/ids_mannheim/korap/resources/Permissions.java
index 6f2c446..e64af5c 100644
--- a/src/main/java/de/ids_mannheim/korap/resources/Permissions.java
+++ b/src/main/java/de/ids_mannheim/korap/resources/Permissions.java
@@ -30,6 +30,14 @@
         }
     }
 
+
+    public static Permission[] read(String ... strings) {
+        Permission[] p = new Permission[strings.length];
+        for (int i = 0; i<strings.length; i++)
+            p[i] = Permission.valueOf(strings[i]);
+        return p;
+    }
+
     private static final byte READ = 1;
     private static final byte WRITE = 2;
     private static final byte DELETE = 4;
diff --git a/src/main/java/de/ids_mannheim/korap/resources/ResourceFactory.java b/src/main/java/de/ids_mannheim/korap/resources/ResourceFactory.java
index 7890b4a..21ceaa7 100644
--- a/src/main/java/de/ids_mannheim/korap/resources/ResourceFactory.java
+++ b/src/main/java/de/ids_mannheim/korap/resources/ResourceFactory.java
@@ -1,5 +1,7 @@
 package de.ids_mannheim.korap.resources;
 
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
 import org.apache.commons.codec.digest.DigestUtils;
 
 import java.util.ArrayList;
@@ -48,7 +50,7 @@
     }
 
 
-    public static KustvaktResource getResource (String type) {
+    public static KustvaktResource getResource (String type) throws KustvaktException {
         return getResource(getResourceClass(type));
     }
 
@@ -71,7 +73,7 @@
 
 
     public static <T extends KustvaktResource> Class<T> getResourceClass (
-            String type) {
+            String type) throws KustvaktException {
         for (Class value : subTypes) {
             if (value == VirtualCollection.class
                     && type.equalsIgnoreCase("collection"))
@@ -83,7 +85,8 @@
                 return value;
             }
         }
-        return null;
+        // todo: throw exception in case of missing parameter!
+        throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT, "resource type could not be identified!");
     }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
index 181d435..a9bcf3a 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
@@ -66,15 +66,15 @@
 
         if (policy.getTarget() == null)
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.MISSING_POLICY_TARGET, policy.toString());
+                    StatusCodes.NO_POLICY_TARGET, policy.toString());
 
         if (policy.getConditions().isEmpty())
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.MISSING_POLICY_CONDITIONS);
+                    StatusCodes.NO_POLICY_CONDITION);
 
         if (policy.getPermissionByte() == 0)
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.MISSING_POLICY_PERMISSION);
+                    StatusCodes.NO_POLICY_PERMISSION);
 
         KeyHolder keyHolder = new GeneratedKeyHolder();
         MapSqlParameterSource np = new MapSqlParameterSource();
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/PolicyEvaluator.java b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyEvaluator.java
index b6dfadb..0fbe1d1 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/PolicyEvaluator.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyEvaluator.java
@@ -19,6 +19,7 @@
 /**
  * Created by hanl on 5/22/14.
  */
+@Deprecated
 public class PolicyEvaluator {
 
     private static final Logger jlog = LoggerFactory
@@ -91,11 +92,11 @@
                         idx++;
                     }
                 }
-                // fixme: what is that?
+                // checks that there are valid policies on higher level resources, so that user is
                 if (idx == 0) {
                     relationError = i;
                     throw new NotAuthorizedException(
-                            StatusCodes.PERMISSION_DENIED, this.getResourceID());
+                            StatusCodes.ACCESS_DENIED, this.getResourceID());
                 }
             }
             this.processed = true;
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/ResourceFinder.java b/src/main/java/de/ids_mannheim/korap/security/ac/ResourceFinder.java
index b27d26a..c319145 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/ResourceFinder.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/ResourceFinder.java
@@ -2,6 +2,7 @@
 
 import de.ids_mannheim.korap.config.ContextHolder;
 import de.ids_mannheim.korap.config.BeansFactory;
+import de.ids_mannheim.korap.exceptions.EmptyResultException;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.interfaces.db.PolicyHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.ResourceOperationIface;
@@ -117,6 +118,9 @@
                 sets.add(r);
             }
         }
+
+        if (sets.isEmpty())
+            throw new EmptyResultException(Arrays.asList(ids).toString());
         return sets;
     }
 
@@ -145,6 +149,7 @@
     }
 
 
+    // fixme: only return field --> extra git repo!
     public <T extends KustvaktResource> Set<T> getResources () {
         return evaluateResources();
     }
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java b/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java
index fb27b4d..1d357e4 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java
@@ -69,7 +69,7 @@
             p = SecurityManager.findbyId(id, user);
         }
         catch (EmptyResultException e) {
-            throw new NotAuthorizedException(StatusCodes.EMPTY_RESULTS,
+            throw new NotAuthorizedException(StatusCodes.NO_VALUE_FOUND,
                     String.valueOf(id));
         }
         return p.getResource();
@@ -87,20 +87,15 @@
     public <T extends KustvaktResource> T findbyStrId (String persistent_id,
             User user, Class<T> type) throws KustvaktException,
             NotAuthorizedException {
-        //T cache = (T) getCache(persistent_id, type);
-        //if (cache != null)
-        //    return cache;
-        //else {
         SecurityManager<T> p;
         try {
             p = SecurityManager.findbyId(persistent_id, user, type);
         }
         catch (EmptyResultException e) {
-            throw new NotAuthorizedException(StatusCodes.EMPTY_RESULTS,
+            throw new NotAuthorizedException(StatusCodes.NO_VALUE_FOUND,
                     persistent_id);
         }
         return p.getResource();
-        //}
     }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java b/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java
index 0fc0863..7e750f9 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java
@@ -163,7 +163,7 @@
             jlog.error(
                     "Reading the resource '{}' is not allowed for user '{}'",
                     this.resource.getPersistentID(), this.user.getUsername());
-            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     evaluator.getResourceID());
         }
     }
@@ -183,7 +183,7 @@
             jlog.error(
                     "Updating the resource '{}' is not allowed for user '{}'",
                     this.resource.getPersistentID(), this.user.getUsername());
-            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     this.evaluator.getResourceID());
         }
 
@@ -209,7 +209,7 @@
                     this.evaluator.getResourceID(), this.user);
         }
         else
-            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     this.evaluator.getResourceID());
     }
 
@@ -248,7 +248,7 @@
         if (!evaluator.isAllowed()) {
             jlog.error("Permission denied for resource id '{}' for user '{}'",
                     this.evaluator.getResourceID(), user.getId());
-            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     this.evaluator.getResourceID());
         }
 
@@ -288,7 +288,7 @@
                     jlog.error(
                             "No policies found for parent '{}' for user '{}'",
                             resource.getParentID(), user.getId());
-                    throw new KustvaktException(StatusCodes.EMPTY_RESULTS);
+                    throw new KustvaktException(StatusCodes.NO_VALUE_FOUND);
                 }
             }
             boolean newid = false;
@@ -324,11 +324,12 @@
                         Permissions.Permission.MODIFY_POLICY);
             }
             catch (EmptyResultException e) {
+                // todo: improve this!
                 jlog.error(
                         "No policies found for '{}' for user '{}'. Resource could not be registered!",
                         resource.getPersistentID(), user.getId());
                 throw new KustvaktException(user.getId(),
-                        StatusCodes.POLICY_CREATE_ERROR,
+                        StatusCodes.POLICY_ERROR_DEFAULT,
                         "Resource could not be registered", resource.toString());
             }
         }
@@ -401,7 +402,7 @@
             jlog.error(
                     "Permission Denied (CREATE_POLICY) on '{}' for user '{}'",
                     this.evaluator.getResourceID(), this.user.getId());
-            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     policy.getTarget());
         }
 
@@ -450,7 +451,6 @@
             jlog.error("No policies found (DELETE_POLICY) on '{}' for '{}'",
                     this.evaluator.getResourceID(), this.user.getId());
             throw new KustvaktException(user.getId(), StatusCodes.NO_POLICIES,
-                    "no policy desicion possible",
                     this.evaluator.getResourceID());
         }
         if (contains(policy)
@@ -460,7 +460,7 @@
         else if (silent) {
             jlog.error("Permission Denied (DELETE_POLICY) on '{}' for '{}'",
                     this.evaluator.getResourceID(), this.user.getId());
-            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     "no policy desicion possible",
                     this.evaluator.getResourceID());
         }
@@ -491,7 +491,7 @@
         else if (silent) {
             jlog.error("Permission Denied (DELETE_POLICY) on '{}' for '{}'",
                     this.evaluator.getResourceID(), this.user.getId());
-            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     this.evaluator.getResourceID());
         }
         this.policies = policydao.getPolicies((int) this.resource.getId(),
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
index 51ec505..81fccf2 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
@@ -78,6 +78,9 @@
     @Override
     public TokenContext getTokenStatus (String token, String host,
             String useragent) throws KustvaktException {
+        if (token == null)
+            throw new KustvaktException(StatusCodes.MISSING_ARGUMENT, "authorization header");
+
         jlog.info("getting session status of token type '{}'",
                 token.split(" ")[0]);
         AuthenticationIface provider = getProvider(
@@ -91,6 +94,8 @@
         TokenContext context = provider.getTokenContext(token);
         if (context != null && TimeUtils.isExpired(context.getExpirationTime()))
             throw new KustvaktException(StatusCodes.EXPIRED);
+        else if (context == null)
+            throw new KustvaktException(StatusCodes.NO_VALUE_FOUND);
 
         //        if (!matchStatus(host, useragent, context))
         //            provider.removeUserSession(token);
@@ -284,12 +289,12 @@
                         deleteAccount(user);
                         throw new WrappedException(new KustvaktException(
                                 unknown.getId(), StatusCodes.EXPIRED,
-                                "account confirmation uri has expired",
+                                "account confirmation uri has expired!",
                                 param.getUriFragment()),
                                 StatusCodes.LOGIN_FAILED, username);
                     }
                     throw new WrappedException(new KustvaktException(
-                            unknown.getId(), StatusCodes.UNCONFIRMED_ACCOUNT),
+                            unknown.getId(), StatusCodes.ACCOUNT_NOT_CONFIRMED),
                             StatusCodes.LOGIN_FAILED, username);
                 }
                 jlog.error("ACCESS DENIED: account not active for '{}'",
@@ -756,7 +761,7 @@
 
             if (data == null)
                 throw new KustvaktException(user.getId(),
-                        StatusCodes.EMPTY_RESULTS, "No data found!",
+                        StatusCodes.NO_VALUE_FOUND, "No data found!",
                         clazz.getSimpleName());
             return data;
         }
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java b/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
index e0b3f51..d7d2b75 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/SessionAuthentication.java
@@ -52,8 +52,6 @@
     public TokenContext getTokenContext(String authenticationToken)
             throws KustvaktException {
         jlog.debug("retrieving user session for user '{}'", authenticationToken);
-        if (authenticationToken == null)
-            throw new KustvaktException(StatusCodes.PERMISSION_DENIED);
         return this.sessions.getSession(authenticationToken);
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java b/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
index 131f0b1..03b9e6e 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/SessionFactory.java
@@ -63,16 +63,15 @@
         jlog.debug("logged in users: {}", loggedInRecord);
         TokenContext context = sessionsObject.get(token);
         if (context != null) {
+            // fixme: set context to respecitve expiratin interval and return context. handler checks expiration later!
             if (isUserSessionValid(token)) {
                 resetInterval(token);
-                return context;
             }
             else
                 throw new KustvaktException(StatusCodes.EXPIRED);
 
         }
-        else
-            throw new KustvaktException(StatusCodes.PERMISSION_DENIED);
+         return context;
     }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/user/TokenContext.java b/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
index 3c8ad0d..a47978d 100644
--- a/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
+++ b/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
@@ -135,11 +135,12 @@
     }
 
 
+    @Deprecated
     public String toJSON () {
         return JsonUtils.toJSON(this.statusMap());
     }
 
-
+    @Deprecated
     public String toResponse () {
         ObjectNode node = JsonUtils.createObjectNode();
         node.put("token", this.getToken());
@@ -149,6 +150,12 @@
     }
 
 
+    public boolean isDemo() {
+        return User.UserFactory.isDemo(this.username);
+    }
+
+
+
     @Override
     public String getName () {
         return this.getUsername();
diff --git a/src/main/java/de/ids_mannheim/korap/user/Userdata.java b/src/main/java/de/ids_mannheim/korap/user/Userdata.java
index 60d851e..bbfddfb 100644
--- a/src/main/java/de/ids_mannheim/korap/user/Userdata.java
+++ b/src/main/java/de/ids_mannheim/korap/user/Userdata.java
@@ -70,7 +70,7 @@
     public void checkRequired () throws KustvaktException {
         String[] fields = missing();
         if (missing().length != 0) {
-            throw new KustvaktException(userId, StatusCodes.MISSING_ARGUMENTS,
+            throw new KustvaktException(userId, StatusCodes.MISSING_ARGUMENT,
                     "User data object not valid. Object has missing fields!",
                     Arrays.asList(fields).toString());
         }
diff --git a/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java b/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java
index 08ceeba..5aa6a5e 100644
--- a/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java
+++ b/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java
@@ -113,6 +113,7 @@
     }
 
 
+    // todo: move to parameter utils
     public static boolean isInteger (String value) {
         try {
             Integer.valueOf(value);
diff --git a/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java b/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
index ee0648c..976c051 100644
--- a/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
@@ -29,7 +29,7 @@
             throw KustvaktResponseHandler.throwAuthenticationException("");
         }
 
-        if(context == null)
+        if(context == null || context.isDemo())
             throw KustvaktResponseHandler.throwAuthenticationException("");
 
         return request;
diff --git a/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java b/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java
deleted file mode 100644
index 708a649..0000000
--- a/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package de.ids_mannheim.korap.web.filter;
-
-import com.sun.jersey.spi.container.ContainerRequest;
-import com.sun.jersey.spi.container.ContainerRequestFilter;
-import com.sun.jersey.spi.container.ContainerResponseFilter;
-import com.sun.jersey.spi.container.ResourceFilter;
-import de.ids_mannheim.korap.config.BeansFactory;
-import de.ids_mannheim.korap.user.TokenContext;
-import de.ids_mannheim.korap.user.User;
-import de.ids_mannheim.korap.utils.TimeUtils;
-import de.ids_mannheim.korap.web.utils.KustvaktContext;
-
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.UriInfo;
-import javax.ws.rs.ext.Provider;
-import java.security.Principal;
-
-/**
- * Created by hanl on 7/15/14.
- */
-@Provider
-public class DefaultFilter implements ContainerRequestFilter, ResourceFilter {
-
-    @Context
-    UriInfo info;
-
-
-    @Override
-    public ContainerRequest filter (ContainerRequest request) {
-        String host = request.getHeaderValue(ContainerRequest.HOST);
-        String ua = request.getHeaderValue(ContainerRequest.USER_AGENT);
-        String authentication = request
-                .getHeaderValue(ContainerRequest.AUTHORIZATION);
-
-        // means that this is the public service
-        if (authentication == null || authentication.isEmpty()) {
-            Principal pr = null;
-            try {
-                pr = request.getUserPrincipal();
-            }
-            catch (UnsupportedOperationException e) {
-                // do nothing
-            }
-            if (pr == null)
-                request.setSecurityContext(new KustvaktContext(
-                        createShorterToken(host, ua)));
-
-        }
-        return request;
-    }
-
-
-    private TokenContext createShorterToken (String host, String agent) {
-        User demo = User.UserFactory.getDemoUser();
-        TokenContext c = new TokenContext();
-        c.setUsername(demo.getUsername());
-        c.setHostAddress(host);
-        c.setUserAgent(agent);
-        c.setExpirationTime(TimeUtils.plusSeconds(
-                BeansFactory.getKustvaktContext().getConfiguration()
-                        .getShortTokenTTL()).getMillis());
-        return c;
-    }
-
-
-    @Override
-    public ContainerRequestFilter getRequestFilter () {
-        return this;
-    }
-
-
-    @Override
-    public ContainerResponseFilter getResponseFilter () {
-        return null;
-    }
-}
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java
index de63612..77f6a8c 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java
@@ -102,18 +102,15 @@
             @QueryParam("perm") List<String> permissions,
             @QueryParam("loc") String loc, @QueryParam("expire") String duration) {
 
-        KustvaktResource resource = ResourceFactory.getResource(type);
-        resource.setPersistentID(persistentid);
-        resource.setDescription(description);
-        resource.setName(name);
-
-        Permissions.Permission[] p = new Permissions.Permission[permissions
-                .size()];
-        for (int idx = 0; idx < permissions.size(); idx++)
-            p[idx] = Permissions.Permission.valueOf(permissions.get(idx)
-                    .toUpperCase());
-
         try {
+            KustvaktResource resource = ResourceFactory.getResource(type);
+            resource.setPersistentID(persistentid);
+            resource.setDescription(description);
+            resource.setName(name);
+
+            Permissions.Permission[] p = Permissions.read(permissions
+                    .toArray(new String[0]));
+
             PolicyBuilder cr = new PolicyBuilder(User.UserFactory.getAdmin())
                     .setConditions(new PolicyCondition(group)).setResources(
                             resource);
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java
index 6f4afe0..d6e2c57 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/AuthService.java
@@ -13,9 +13,7 @@
 import de.ids_mannheim.korap.utils.KustvaktLogger;
 import de.ids_mannheim.korap.utils.ServiceInfo;
 import de.ids_mannheim.korap.web.KustvaktServer;
-import de.ids_mannheim.korap.web.filter.AuthFilter;
-import de.ids_mannheim.korap.web.filter.DefaultFilter;
-import de.ids_mannheim.korap.web.filter.PiwikFilter;
+import de.ids_mannheim.korap.web.filter.*;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 import org.slf4j.Logger;
 
@@ -79,7 +77,7 @@
     // fixme: moved to user
     @GET
     @Path("status")
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class })
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class, BlockingFilter.class })
     public Response getStatus (@Context SecurityContext context,
             @HeaderParam(ContainerRequest.USER_AGENT) String agent,
             @HeaderParam(ContainerRequest.HOST) String host,
@@ -91,6 +89,7 @@
 
     @GET
     @Path("apiToken")
+    @ResourceFilters({HeaderFilter.class})
     public Response requestAPIToken (@Context HttpHeaders headers,
             @Context Locale locale,
             @HeaderParam(ContainerRequest.USER_AGENT) String agent,
@@ -100,15 +99,16 @@
         List<String> auth = headers
                 .getRequestHeader(ContainerRequest.AUTHORIZATION);
 
-        if (auth == null)
-            throw KustvaktResponseHandler
-                    .throwit(StatusCodes.PERMISSION_DENIED);
+
+       // if (auth == null)
+        //    throw KustvaktResponseHandler
+        //            .throwit(StatusCodes.ACCESS_DENIED);
         String[] values = BasicHttpAuth.decode(auth.get(0));
 
         // "Invalid syntax for username and password"
         if (values == null)
             throw KustvaktResponseHandler
-                    .throwit(StatusCodes.PERMISSION_DENIED);
+                    .throwit(StatusCodes.ACCESS_DENIED);
 
         if (values[0].equalsIgnoreCase("null")
                 | values[1].equalsIgnoreCase("null"))
@@ -169,7 +169,7 @@
 
         if (auth == null)
             throw KustvaktResponseHandler
-                    .throwit(StatusCodes.PERMISSION_DENIED);
+                    .throwit(StatusCodes.ACCESS_DENIED);
 
         String[] values = BasicHttpAuth.decode(auth.get(0));
         //        authentication = StringUtils.stripTokenType(authentication);
@@ -180,7 +180,7 @@
         // "Invalid syntax for username and password"
         if (values == null)
             throw KustvaktResponseHandler
-                    .throwit(StatusCodes.PERMISSION_DENIED);
+                    .throwit(StatusCodes.BAD_CREDENTIALS);
 
         if (values[0].equalsIgnoreCase("null")
                 | values[1].equalsIgnoreCase("null"))
@@ -238,7 +238,7 @@
     //fixme: moved from userservice
     @GET
     @Path("logout")
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class, PiwikFilter.class })
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class, PiwikFilter.class })
     public Response logout (@Context SecurityContext ctx, @Context Locale locale) {
         TokenContext context = (TokenContext) ctx.getUserPrincipal();
         try {
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/OAuthService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/OAuthService.java
index 02d9f7f..5fdbe62 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/OAuthService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/OAuthService.java
@@ -14,7 +14,7 @@
 import de.ids_mannheim.korap.web.KustvaktServer;
 import de.ids_mannheim.korap.web.filter.AuthFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
-import de.ids_mannheim.korap.web.filter.DefaultFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
@@ -118,7 +118,7 @@
 
     @GET
     @Path("info")
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class, PiwikFilter.class })
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class, PiwikFilter.class })
     public Response getStatus (@Context SecurityContext context,
             @QueryParam("scope") String scopes) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
index a3585af..06b6106 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
@@ -27,12 +27,11 @@
 import de.ids_mannheim.korap.web.TRACE;
 import de.ids_mannheim.korap.web.filter.AuthFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
-import de.ids_mannheim.korap.web.filter.DefaultFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Bean;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.*;
@@ -43,8 +42,7 @@
  * @date 29/01/2014
  */
 @Path(KustvaktServer.API_VERSION + "/")
-@ResourceFilters({ AuthFilter.class, DefaultFilter.class, PiwikFilter.class,
-        BlockingFilter.class })
+@ResourceFilters({ AuthFilter.class, DemoUserFilter.class, PiwikFilter.class})
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 public class ResourceService {
 
@@ -90,13 +88,13 @@
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         Set<KustvaktResource> resources = new HashSet<>();
         type = StringUtils.normalize(type);
-        Class cl_type = ResourceFactory.getResourceClass(type);
-        if (cl_type == null) {
-            throw KustvaktResponseHandler.throwit(StatusCodes.REQUEST_INVALID,
-                    "Resource type not available!", "");
-        }
 
         try {
+            Class cl_type = ResourceFactory.getResourceClass(type);
+            if (cl_type == null)
+                throw KustvaktResponseHandler.throwit(StatusCodes.MISSING_ARGUMENT,
+                        "Resource type not available!", "");
+
             User user = controller.getUser(ctx.getUsername());
 
             resources = ResourceFinder.search(user,
@@ -137,28 +135,34 @@
             @PathParam("id") String id) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         type = StringUtils.normalize(type);
-        Class cl_type = ResourceFactory.getResourceClass(type);
         KustvaktResource resource;
         try {
-            User user = controller.getUser(ctx.getUsername());
-            if (StringUtils.isInteger(id))
-                resource = resourceHandler.findbyIntId(Integer.valueOf(id),
-                        user);
-            else
-                resource = resourceHandler.findbyStrId(id, user,
-                        ResourceFactory.getResourceClass(type));
-        }
-        catch (KustvaktException e) {
-            if (e.getStatusCode() != StatusCodes.PERMISSION_DENIED)
-                throw KustvaktResponseHandler.throwit(e);
+            Class cl_type = ResourceFactory.getResourceClass(type);
 
-            try {
+            if (ctx.isDemo()) {
                 Set set = ResourceFinder.searchPublicFiltered(cl_type, id);
                 resource = (KustvaktResource) set.toArray()[0];
+            } else {
+                User user = controller.getUser(ctx.getUsername());
+                if (StringUtils.isInteger(id))
+                    resource = resourceHandler.findbyIntId(Integer.valueOf(id),
+                            user);
+                else
+                    resource = resourceHandler.findbyStrId(id, user,
+                            cl_type);
             }
-            catch (KustvaktException e1) {
-                throw KustvaktResponseHandler.throwit(e);
-            }
+        }
+        catch (KustvaktException e) {
+            //if (e.getStatusCode() != StatusCodes.ACCESS_DENIED)
+            throw KustvaktResponseHandler.throwit(e);
+
+            //try {
+            //    Set set = ResourceFinder.searchPublicFiltered(cl_type, id);
+             //   resource = (KustvaktResource) set.toArray()[0];
+            //}
+            //catch (KustvaktException e1) {
+            //    throw KustvaktResponseHandler.throwit(e);
+            //}
         }
         return Response.ok(JsonUtils.toJSON(resource.toMap())).build();
     }
@@ -378,29 +382,25 @@
         String query = "";
         KustvaktResource resource;
         try {
-            User user = controller.getUser(ctx.getUsername());
 
-            if (StringUtils.isInteger(id))
-                resource = this.resourceHandler.findbyIntId(
-                        Integer.valueOf(id), user);
-            else
-                resource = this.resourceHandler.findbyStrId(id, user,
-                        ResourceFactory.getResourceClass(type));
-        }
-        //todo: instead of throwing exception, build notification and rewrites into result query
-        catch (KustvaktException e) {
-            if (e.getStatusCode() != StatusCodes.PERMISSION_DENIED) {
-                jlog.error("Exception encountered: {}", e.string());
-                throw KustvaktResponseHandler.throwit(e);
-            }
-            try {
+            if (ctx.isDemo()) {
                 Set set = ResourceFinder.searchPublicFiltered(
                         ResourceFactory.getResourceClass(type), id);
                 resource = (KustvaktResource) set.toArray()[0];
+            } else {
+                User user = controller.getUser(ctx.getUsername());
+                if (StringUtils.isInteger(id))
+                    resource = this.resourceHandler.findbyIntId(
+                            Integer.valueOf(id), user);
+                else
+                    resource = this.resourceHandler.findbyStrId(id, user,
+                            ResourceFactory.getResourceClass(type));
             }
-            catch (KustvaktException e1) {
-                throw KustvaktResponseHandler.throwit(e);
-            }
+        }
+        //todo: instead of throwing exception, build notification and rewrites into result query
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
         }
 
         if (resource != null) {
@@ -639,7 +639,7 @@
         String stats = searchKrill.getStatistics(builder.toJSON());
 
         if (stats.contains("-1"))
-            throw KustvaktResponseHandler.throwit(StatusCodes.EMPTY_RESULTS);
+            throw KustvaktResponseHandler.throwit(StatusCodes.NO_VALUE_FOUND);
 
         return Response.ok(stats).build();
     }
@@ -664,12 +664,13 @@
         type = StringUtils.normalize(type);
         id = StringUtils.decodeHTML(id);
 
-        Class sl = ResourceFactory.getResourceClass(type);
-        if (!VirtualCollection.class.equals(sl) & !Corpus.class.equals(sl))
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
-                    "Requested Resource type not supported", type);
 
         try {
+            Class sl = ResourceFactory.getResourceClass(type);
+            if (!VirtualCollection.class.equals(sl) & !Corpus.class.equals(sl))
+                throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+                        "Requested Resource type not supported", type);
+
             User user = controller.getUser(ctx.getUsername());
             KustvaktResource resource;
             if (StringUtils.isInteger(id))
@@ -796,15 +797,17 @@
         reference = StringUtils.decodeHTML(reference);
         Map vals = new HashMap();
         User user;
+        Class ctype;
         try {
+            ctype = ResourceFactory
+                    .getResourceClass(type);
             user = controller.getUser(ctx.getUsername());
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
             throw KustvaktResponseHandler.throwit(e);
         }
-        if (VirtualCollection.class.equals(ResourceFactory
-                .getResourceClass(type))) {
+        if (VirtualCollection.class.equals(ctype)) {
             VirtualCollection cachetmp, collection;
 
             JsonNode base;
@@ -885,16 +888,19 @@
         reference = StringUtils.decodeHTML(reference);
         Map vals = new HashMap();
         User user;
+        Class ctype;
         try {
+            ctype = ResourceFactory
+                    .getResourceClass(type);
+
             user = controller.getUser(ctx.getUsername());
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
             throw KustvaktResponseHandler.throwit(e);
         }
-        if (VirtualCollection.class.equals(ResourceFactory
-                .getResourceClass(type))) {
 
+        if (VirtualCollection.class.equals(ctype)) {
             VirtualCollection cachetmp, collection;
 
             KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
@@ -1031,12 +1037,12 @@
                 }
                 catch (EmptyResultException e) {
                     throw KustvaktResponseHandler.throwit(
-                            StatusCodes.EMPTY_RESULTS, "Resource not found!",
+                            StatusCodes.NO_VALUE_FOUND, "Resource not found!",
                             id);
                 }
                 catch (NotAuthorizedException e) {
                     throw KustvaktResponseHandler.throwit(
-                            StatusCodes.PERMISSION_DENIED, "Permission denied",
+                            StatusCodes.ACCESS_DENIED, "Permission denied",
                             id);
                 }
 
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
index 9ed2fa4..03a9baa 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
@@ -18,7 +18,7 @@
 import de.ids_mannheim.korap.web.KustvaktServer;
 import de.ids_mannheim.korap.web.filter.AuthFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
-import de.ids_mannheim.korap.web.filter.DefaultFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
@@ -103,7 +103,7 @@
     @POST
     @Path("update")
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response updateAccount (@Context SecurityContext ctx, String json) {
         TokenContext context = (TokenContext) ctx.getUserPrincipal();
@@ -144,7 +144,7 @@
             e.printStackTrace();
             throw KustvaktResponseHandler.throwit(e);
         }
-        return Response.ok("success").build();
+        return Response.ok().build();
     }
 
 
@@ -238,7 +238,7 @@
 
     @GET
     @Path("settings")
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response getUserSettings (@Context SecurityContext context,
             @Context Locale locale) {
@@ -262,7 +262,7 @@
     @POST
     @Path("settings")
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response updateSettings (@Context SecurityContext context,
             @Context Locale locale, MultivaluedMap form) {
@@ -297,7 +297,7 @@
 
     @GET
     @Path("details")
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response getDetails (@Context SecurityContext context,
             @Context Locale locale, @QueryParam("pointer") String pointer) {
@@ -323,7 +323,7 @@
     @POST
     @Path("details")
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response updateDetails (@Context SecurityContext context,
             @Context Locale locale, MultivaluedMap form) {
@@ -356,7 +356,7 @@
     @POST
     @Path("queries")
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response updateQueries (@Context SecurityContext context, String json) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
@@ -408,7 +408,7 @@
 
 
     @DELETE
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response deleteUser (@Context SecurityContext context) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
@@ -428,7 +428,7 @@
 
     @GET
     @Path("queries")
-    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+    @ResourceFilters({ AuthFilter.class, DemoUserFilter.class,
             PiwikFilter.class, BlockingFilter.class })
     public Response getQueries (@Context SecurityContext context,
             @Context Locale locale) {
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java b/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
index ca6ef34..3ede08c 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
@@ -284,7 +284,7 @@
         // todo: policy override in extension!
         String stats = searchKrill.getStatistics(builder.toJSON());
         if (stats.contains("-1"))
-            throw KustvaktResponseHandler.throwit(StatusCodes.EMPTY_RESULTS);
+            throw KustvaktResponseHandler.throwit(StatusCodes.NO_VALUE_FOUND);
 
         return Response.ok(stats).build();
     }
diff --git a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
index 66eb5c3..85b0f46 100644
--- a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
@@ -82,7 +82,7 @@
     private static Response.Status getStatus (int code) {
         Response.Status status = Response.Status.BAD_REQUEST;
         switch (code) {
-            case StatusCodes.EMPTY_RESULTS:
+            case StatusCodes.NO_VALUE_FOUND:
                 status = Response.Status.NO_CONTENT;
                 break;
             case StatusCodes.ILLEGAL_ARGUMENT:
diff --git a/src/main/resources/codes.kustvakt b/src/main/resources/codes.kustvakt
index b2fa1fb..3365699 100644
--- a/src/main/resources/codes.kustvakt
+++ b/src/main/resources/codes.kustvakt
@@ -1,36 +1,93 @@
-# generic non localized messages for API error codes
+# generic non localized messages for API error and message codes
+# below 500 generic status codes for low level function
+# 501 - 999 specific section codes for database, validation, 
+# upper 1000 service messages as feedback for user (partially masking low level codes) with optional descriptin of low level error
 
-# standard system errors #
-100 : "No Entry found!"
-101 : "The request could not be processed!"
+
+# standard system errors
+100 : "Default Kustvakt failure!"
+101 : "No Entry found!"
 102 : "Entry exists already!"
-103 : "Status ok!"
-104 : "Unsupported Overation!"
-105 : "Illegal argument found. Request could not be processed!"
-106 : "Connection Error"
-107 : "No changes"
-108 : "Parameter Validation failed!"
-109 : ""
-110 : "Not supported!"
+103 : "Unsupported operation!"
+104 : "Illegal argument found. Request could not be processed!"
+105 : "Missing argument!"
+106 : "Connection Error!"
+107 : "Missing arguments!"
+108 : "Function Not supported!"
 
 
-# 200 codes for user account/ authenticaation services
-200 : "Account deactivated. Please verify account before using this API"
-201 : "Account confirmation failed. Please contact an adminstrator"
-202 : "Already logged in!"
-203 : ""
-204 : "Authentication credentials expired!"
-205 : "Bad credentials!"
-206 : ""
-207 : "Username already exists"
-208 : "Password reset failed"
-209 : ""
-210 : "Login successful!"
-211 : "Login failed!"
-212 : "Logout successful!"
-213 : "Logout failed!"
-214 : "Client registration failed!"
-215 : "Deleting client information failed!"
-216 : "Client could not be authorized!"
+# 400 codes for authorization and rewrite functions
 
+400 : "Policy failure!"
+# permission denied is a service code, here it should be more 
+# specific about the nature of the error/message
+401 : ""
+402 : "Unsupported resource"
+403 : "Failed rewrite!"
+404 : ""
+405 : "Resource could not be found" --> missing resource
+406 : "No target for resource policy!"
+407 : "No condition for resource policy!"
+408 : "No permission for resource policy!"
+409 : "No policies for resource!"
+
+# 500 database errors
+
+500 : ""
+501 : "Database retrieval failure!"
+502 : "Database insert failure!"
+503 : "Database delete failure!"
+504 : "Database update failure!"
+505 : ""
+506 : ""
+507 : ""
+508 : ""
+509 : ""
+510 : ""
+511 : ""
+512 : ""
+513 : ""
+
+# validation messages
+
+600 : ""
+601 : ""
+602 : ""
+603 : ""
+604 : ""
+605 : ""
+
+
+
+# 1000 service status message codes for logging
+
+1000 : "Status Ok!"
+1001 : "Nothing changed!"
+1002 : "Request could not be processed!"
+1003 : "Access denied!"
+1004 : ""
+1005 : ""
+1006 : ""
+1007 : ""
+1008 : ""
+1009 : ""
+1010 : ""
+
+
+# 2000 codes for REST API services
+2000 : "Account deactivated. Please verify account before using this API"
+2001 : "Account confirmation failed. Please contact an adminstrator"
+2002 : "Already logged in!"
+2003 : "Authentication credentials expired!"
+2004 : "Bad credentials!"
+2005 : ""
+2006 : "Password reset failed"
+
+2007 : "Login successful!"
+2008 : "Login failed!"
+2009 : "Logout successful!"
+2010 : "Logout failed!"
+2011 : "Client registration failed!"
+2012 : "Deleting client information failed!"
+2013 : "Client could not be authorized!"