diff --git a/pom.xml b/pom.xml
index bab503a..4594c94 100644
--- a/pom.xml
+++ b/pom.xml
@@ -176,7 +176,7 @@
                     <excludes>
                         <exclude>**/*APITest.java</exclude>
                         <exclude>de/ids_mannheim/korap/suites/*.java</exclude>
-                		<exclude>**/ResouceServiceServerTest.java</exclude>
+                		<exclude>**/KustvaktServerTest.java</exclude>
                     </excludes>
                     <includes>
                         <include>de/ids_mannheim/korap/**/*.java</include>
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/db/PolicyHandlerIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/db/PolicyHandlerIface.java
index 8c55953..fe20a25 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/db/PolicyHandlerIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/db/PolicyHandlerIface.java
@@ -1,6 +1,7 @@
 package de.ids_mannheim.korap.interfaces.db;
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.resources.Foundry;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.security.Parameter;
 import de.ids_mannheim.korap.security.PolicyCondition;
@@ -36,7 +37,9 @@
 
     List<SecurityPolicy> getPolicies (PolicyCondition condition,
             Class<? extends KustvaktResource> clazz, Byte perm);
-
+    
+    List<SecurityPolicy> getPoliciesByPersistentId (PolicyCondition policyCondition,
+            Class<? extends KustvaktResource> clazz, byte perm, String id);
 
     /**
      * @param policy
@@ -196,4 +199,5 @@
 
     int size ();
 
+
 }
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 6ab19bf..43c4ea9 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
@@ -5,6 +5,7 @@
 import de.ids_mannheim.korap.exceptions.dbException;
 import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
 import de.ids_mannheim.korap.interfaces.db.PolicyHandlerIface;
+import de.ids_mannheim.korap.resources.Foundry;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.resources.ResourceFactory;
 import de.ids_mannheim.korap.security.Parameter;
@@ -98,8 +99,7 @@
         }
         catch (DataAccessException e) {
             e.printStackTrace();
-            jlog.error(
-                    "Operation (INSERT) not possible for '{}' for user '{}'",
+            jlog.error("Operation (INSERT) not possible for '{}' for user '{}'",
                     policy.toString(), user.getId());
             throw new dbException(user.getId(), "policy_store",
                     StatusCodes.DB_INSERT_FAILED, policy.toString());
@@ -117,7 +117,8 @@
      */
     // benchmark this!
     @Override
-    public void mapConstraints (SecurityPolicy policy) throws KustvaktException {
+    public void mapConstraints (SecurityPolicy policy)
+            throws KustvaktException {
         final String cond = "INSERT INTO group_ref (group_id, policy_id) VALUES (:group, :policyID);";
         final String remove = "DELETE FROM group_ref WHERE group_id=:group and policy_id=:policyID;";
         try {
@@ -128,8 +129,8 @@
                         .getRemoved().size()];
                 for (Integer toremove : policy.getRemoved()) {
                     MapSqlParameterSource source = new MapSqlParameterSource();
-                    source.addValue("group", conditions.get(toremove)
-                            .getSpecifier());
+                    source.addValue("group",
+                            conditions.get(toremove).getSpecifier());
                     source.addValue("policyID", policy.getID());
                     sources_removed[idx++] = source;
                 }
@@ -143,7 +144,8 @@
                         .getAdded().size()];
                 for (Integer add : policy.getAdded()) {
                     MapSqlParameterSource source = new MapSqlParameterSource();
-                    source.addValue("group", conditions.get(add).getSpecifier());
+                    source.addValue("group",
+                            conditions.get(add).getSpecifier());
                     source.addValue("policyID", policy.getID());
                     sources[idx++] = source;
                 }
@@ -173,17 +175,17 @@
 
             try {
                 final Integer[] results = new Integer[2];
-                jdbcTemplate
-                        .query("SELECT COUNT(*) as total, (select count(*) from group_users where user_id=:userid and "
+                jdbcTemplate.query(
+                        "SELECT COUNT(*) as total, (select count(*) from group_users where user_id=:userid and "
                                 + "group_id=:name) as users FROM group_store WHERE name=:name",
-                                param, new RowCallbackHandler() {
-                                    @Override
-                                    public void processRow (ResultSet rs)
-                                            throws SQLException {
-                                        results[0] = rs.getInt("total");
-                                        results[1] = rs.getInt("users");
-                                    }
-                                });
+                        param, new RowCallbackHandler() {
+                            @Override
+                            public void processRow (ResultSet rs)
+                                    throws SQLException {
+                                results[0] = rs.getInt("total");
+                                results[1] = rs.getInt("users");
+                            }
+                        });
 
                 boolean admin = false;
                 if (results[0] == 0) {
@@ -191,8 +193,8 @@
                     this.createCondition(cond, user);
                 }
                 if (results[1] == 0)
-                    this.addToCondition(Arrays.asList(user.getUsername()),
-                            cond, admin);
+                    this.addToCondition(Arrays.asList(user.getUsername()), cond,
+                            admin);
             }
             catch (DataAccessException e) {
                 jlog.error(
@@ -282,6 +284,50 @@
         }
     }
 
+    // EM: should only return one policy
+    @Override
+    public List<SecurityPolicy> getPoliciesByPersistentId (
+            PolicyCondition condition, Class<? extends KustvaktResource> clazz, byte perm,
+            String persistentId) {
+
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("cond", condition.getSpecifier());
+        param.addValue("perm", perm);
+        param.addValue("type", ResourceFactory.getResourceMapping(clazz));
+        param.addValue("en", TimeUtils.getNow().getMillis());
+        param.addValue("persistentId", persistentId);
+        String sql_new = "select pv.*, pv.perm & :perm as allowed, "
+                + "rh.depth, (select max(depth) from resource_tree "
+                + "where child_id=rh.child_id) as max_depth from policy_view as pv "
+                + "inner join resource_tree as rh on rh.parent_id=pv.id "
+                + "where "
+                + "pv.persistent_id =:persistentId and "
+                + "pv.enable <= :en and (pv.expire > :en or pv.expire is NULL) and "
+                + "pv.group_id=:cond and pv.type=:type";
+
+        try {
+            return this.jdbcTemplate.query(sql_new, param,
+                    new ResultSetExtractor<List<SecurityPolicy>>() {
+
+                        @Override
+                        public List<SecurityPolicy> extractData (ResultSet rs)
+                                throws SQLException, DataAccessException {
+                            List<SecurityPolicy> policies = SecurityRowMappers
+                                    .mapConditionPolicies(rs);
+                            if (policies.size() > 1)
+                                jlog.warn(
+                                        "Policy ids are not uniques. Found more than one policy for id:"
+                                                + policies.get(0).getID());
+                            return policies;
+                        }
+                    });
+        }
+        catch (DataAccessException e) {
+            jlog.error(e.getLocalizedMessage());
+            return Collections.emptyList();
+        }
+    }
+
 
     @Override
     public List<SecurityPolicy>[] getPolicies (String target, final User user,
@@ -290,7 +336,7 @@
         param.addValue("target", target);
         param.addValue("userid", user.getId());
         param.addValue("perm", perm);
-        param.addValue("en",TimeUtils.getNow().getMillis());
+        param.addValue("en", TimeUtils.getNow().getMillis());
 
         String sql_new = "select pv.*, pv.perm & :perm as allowed, "
                 + "rh.depth, (select max(depth) from resource_tree "
@@ -491,6 +537,7 @@
     // todo: access to leave node also means that the path to the root for that permission is allowed,
     // todo: thus all upper resource access is as well allowed
 
+
     //todo: remove not used context?! --> who is allowed to do so?
     @Override
     public int deletePolicy (SecurityPolicy policy, User user)
@@ -499,14 +546,13 @@
         param.addValue("id", policy.getID());
 
         try {
-            this.jdbcTemplate.update(
-                    "DELETE FROM group_ref WHERE policy_id=:id", param);
-            return this.jdbcTemplate.update(
-                    "DELETE FROM policy_store WHERE id=:id", param);
+            this.jdbcTemplate
+                    .update("DELETE FROM group_ref WHERE policy_id=:id", param);
+            return this.jdbcTemplate
+                    .update("DELETE FROM policy_store WHERE id=:id", param);
         }
         catch (DataAccessException e) {
-            jlog.error(
-                    "Operation (DELETE) not possible for '{}' for user '{}'",
+            jlog.error("Operation (DELETE) not possible for '{}' for user '{}'",
                     policy.toString(), user.getId());
             throw new dbException(user.getId(), "policy_store, group_ref",
                     StatusCodes.DB_DELETE_FAILED, policy.toString());
@@ -524,8 +570,7 @@
             return this.jdbcTemplate.update(sql, param);
         }
         catch (DataAccessException e) {
-            jlog.error(
-                    "Operation (DELETE) not possible for '{}' for user '{}'",
+            jlog.error("Operation (DELETE) not possible for '{}' for user '{}'",
                     id, user.getId());
             throw new dbException(user.getId(), "policy_store",
                     StatusCodes.DB_DELETE_FAILED, id);
@@ -549,8 +594,7 @@
             return result;
         }
         catch (DataAccessException e) {
-            jlog.error(
-                    "Operation (UPDATE) not possible for '{}' for user '{}'",
+            jlog.error("Operation (UPDATE) not possible for '{}' for user '{}'",
                     policy.toString(), user.getId());
             throw new dbException(user.getId(), "policy_store",
                     StatusCodes.DB_UPDATE_FAILED, policy.toString());
@@ -572,8 +616,7 @@
             return this.jdbcTemplate.queryForObject(sql1, param, Integer.class);
         }
         catch (DataAccessException e) {
-            jlog.error(
-                    "Operation (SELECT) not possible for '{}' for user '{}'",
+            jlog.error("Operation (SELECT) not possible for '{}' for user '{}'",
                     policy.getTarget(), user.getId());
             throw new dbException(user.getId(), "policy_store",
                     StatusCodes.DB_GET_FAILED, policy.toString());
@@ -614,8 +657,7 @@
             return this.jdbcTemplate.queryForObject(sql, param, Integer.class);
         }
         catch (DataAccessException e) {
-            jlog.error(
-                    "Operation (SELECT) not possible for '{}' for user '{}'",
+            jlog.error("Operation (SELECT) not possible for '{}' for user '{}'",
                     group, user.getId());
             throw new dbException(user.getId(), "policy_store",
                     StatusCodes.DB_GET_FAILED, group);
@@ -633,8 +675,8 @@
         param.addValue("sy", condition.getFlags().get(Attributes.SYM_USE));
         param.addValue("ex", condition.getFlags().get(Attributes.LICENCE));
         try {
-            this.jdbcTemplate.update(
-                    "INSERT INTO group_store (name, sym_use, export, commercial) "
+            this.jdbcTemplate
+                    .update("INSERT INTO group_store (name, sym_use, export, commercial) "
                             + "VALUES (:name, :sy, :ex, :com);", param);
         }
         catch (DataAccessException e) {
@@ -662,7 +704,8 @@
         }
         catch (DataAccessException e) {
             //todo: test with mysql
-            if (!e.getMessage().toLowerCase().contains("UNIQUE".toLowerCase())) {
+            if (!e.getMessage().toLowerCase()
+                    .contains("UNIQUE".toLowerCase())) {
                 jlog.error(
                         "Operation (INSERT) not possible for '{}' for user '{}'",
                         condition.toString(), username);
@@ -731,8 +774,8 @@
                 throw new KustvaktException(
                         "Operation (INSERT) not possible for '"
                                 + condition.toString() + "' for user '"
-                                + usernames + "'", e,
-                        StatusCodes.CONNECTION_ERROR);
+                                + usernames + "'",
+                        e, StatusCodes.CONNECTION_ERROR);
             }
             return null;
         }
@@ -759,8 +802,7 @@
             this.jdbcTemplate.batchUpdate(del, sources);
         }
         catch (DataAccessException e) {
-            jlog.error(
-                    "Operation (DELETE) not possible for '{}' for user '{}'",
+            jlog.error("Operation (DELETE) not possible for '{}' for user '{}'",
                     condition.toString(), usernames);
             throw new KustvaktException(e, StatusCodes.CONNECTION_ERROR);
         }
@@ -813,7 +855,8 @@
         MapSqlParameterSource source = new MapSqlParameterSource();
         source.addValue("key", key);
         final String select = "SELECT COUNT(*) FROM param_store WHERE p_key=:key;";
-        return this.jdbcTemplate.queryForObject(select, source, Integer.class) == 1;
+        return this.jdbcTemplate.queryForObject(select, source,
+                Integer.class) == 1;
     }
 
 
@@ -859,5 +902,4 @@
             return 0;
         }
     }
-
 }
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 d1a3162..d3694b8 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
@@ -1,9 +1,7 @@
 package de.ids_mannheim.korap.web.service.full;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -14,7 +12,6 @@
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.core.SecurityContext;
 
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
@@ -24,12 +21,10 @@
 import com.sun.jersey.spi.container.ResourceFilters;
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
-import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.handlers.DocumentDao;
-import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.resources.Document;
 import de.ids_mannheim.korap.resources.KustvaktResource;
@@ -37,7 +32,6 @@
 import de.ids_mannheim.korap.resources.ResourceFactory;
 import de.ids_mannheim.korap.security.PolicyCondition;
 import de.ids_mannheim.korap.security.ac.PolicyBuilder;
-import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
@@ -47,7 +41,9 @@
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 
 /**
- * Created by hanl on 6/11/14.
+ * @author hanl, margaretha 
+ * Created date 6/11/14. 
+ * Last update: 04/2017
  */
 @Path(KustvaktServer.API_VERSION + "/admin")
 @ResourceFilters({ AdminFilter.class, PiwikFilter.class })
@@ -56,7 +52,6 @@
 
     private static Logger jlog = LoggerFactory.getLogger(AdminService.class);
 
-    private AuthenticationManagerIface authManager;
     private AuditingIface auditingController;
     private DocumentDao documentDao;
 
@@ -64,13 +59,11 @@
     public AdminService () {
         this.auditingController = BeansFactory.getKustvaktContext()
                 .getAuditingProvider();
-        this.authManager = BeansFactory.getKustvaktContext()
-                .getAuthenticationManager();
-        this.documentDao = new DocumentDao(BeansFactory.getKustvaktContext()
-                .getPersistenceClient());
+        this.documentDao = new DocumentDao(
+                BeansFactory.getKustvaktContext().getPersistenceClient());
     }
 
-
+    // EM: not documented and tested, not sure what the purpose of the service is
     @GET
     @Path("audit/{type}")
     public Response getAudits (@PathParam("type") String type,
@@ -111,8 +104,41 @@
             @QueryParam("description") String description,
             @QueryParam("group") String group,
             @QueryParam("perm") List<String> permissions,
-            @QueryParam("loc") String loc, @QueryParam("expire") String duration, 
-            @Context HttpContext context) {
+            @QueryParam("loc") String loc,
+            @QueryParam("expire") String duration, @Context HttpContext context)
+            throws KustvaktException {
+
+        if (type == null | type.isEmpty()) {
+            KustvaktException e = new KustvaktException(
+                    StatusCodes.MISSING_ARGUMENT,
+                    "The value of parameter type is missing.");
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        else if (name == null | name.isEmpty()) {
+            KustvaktException e = new KustvaktException(
+                    StatusCodes.MISSING_ARGUMENT,
+                    "The value of parameter name is missing.");
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        else if (description == null | description.isEmpty()) {
+            KustvaktException e = new KustvaktException(
+                    StatusCodes.MISSING_ARGUMENT,
+                    "The value of parameter description is missing.");
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        else if (group == null | group.isEmpty()) {
+            KustvaktException e = new KustvaktException(
+                    StatusCodes.MISSING_ARGUMENT,
+                    "The value of parameter group is missing.");
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        else if (permissions == null | permissions.isEmpty()) {
+            KustvaktException e = new KustvaktException(
+                    StatusCodes.MISSING_ARGUMENT,
+                    "The value of parameter permissions is missing.");
+            throw KustvaktResponseHandler.throwit(e);
+        }
+
 
         try {
             KustvaktResource resource = ResourceFactory.getResource(type);
@@ -120,22 +146,23 @@
             resource.setDescription(description);
             resource.setName(name);
 
-            Permissions.Permission[] p = Permissions.read(permissions
-                    .toArray(new String[0]));
-          
+            Permissions.Permission[] p = Permissions
+                    .read(permissions.toArray(new String[0]));
+
             User user = (User) context.getProperties().get("user");
-        	
+
             PolicyBuilder pb = new PolicyBuilder(user)
                     .setConditions(new PolicyCondition(group))
                     .setResources(resource);
-            
-            if (loc != null && !loc.isEmpty())
+
+            if (loc != null && !loc.isEmpty()){
                 pb.setLocation(loc);
-
-            if (duration != null && !duration.isEmpty())
-                pb.setContext(TimeUtils.getNow().getMillis(),
-                        TimeUtils.convertTimeToSeconds(duration));
-
+            }
+            if (duration != null && !duration.isEmpty()){
+                long now = TimeUtils.getNow().getMillis();
+                pb.setContext(now,
+                        now + TimeUtils.convertTimeToSeconds(duration));
+            }
             pb.setPermissions(p);
             pb.create();
         }
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 feee22e..5eb8f1b 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
@@ -64,976 +64,1140 @@
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 
 /**
- * @author hanl
+ * @author hanl, margaretha
  * @date 29/01/2014
+ *       update 04/2017
  */
 @Path(KustvaktServer.API_VERSION + "/")
 @ResourceFilters({ AuthFilter.class, DemoUserFilter.class, PiwikFilter.class })
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 public class ResourceService {
 
-	private static Logger jlog = LoggerFactory.getLogger(ResourceService.class);
+    private static Logger jlog = LoggerFactory.getLogger(ResourceService.class);
 
-	private SearchKrill searchKrill;
-	private ResourceHandler resourceHandler;
-	private AuthenticationManagerIface controller;
-	private ClientsHandler graphDBhandler;
-	private KustvaktConfiguration config;
-	private RewriteHandler processor;
+    private SearchKrill searchKrill;
+    private ResourceHandler resourceHandler;
+    private AuthenticationManagerIface controller;
+    private ClientsHandler graphDBhandler;
+    private KustvaktConfiguration config;
+    private RewriteHandler processor;
 
-	public ResourceService() {
-		this.controller = BeansFactory.getKustvaktContext().getAuthenticationManager();
-		this.config = BeansFactory.getKustvaktContext().getConfiguration();
-		this.resourceHandler = new ResourceHandler();
-		this.searchKrill = new SearchKrill(config.getIndexDir());
-		UriBuilder builder = UriBuilder.fromUri("http://10.0.10.13").port(9997);
-		this.graphDBhandler = new ClientsHandler(builder.build());
 
-		this.processor = new RewriteHandler();
-		this.processor.defaultRewriteConstraints();
-		this.processor.insertBeans(BeansFactory.getKustvaktContext());
-	}
+    public ResourceService () {
+        this.controller = BeansFactory.getKustvaktContext()
+                .getAuthenticationManager();
+        this.config = BeansFactory.getKustvaktContext().getConfiguration();
+        this.resourceHandler = new ResourceHandler();
+        this.searchKrill = new SearchKrill(config.getIndexDir());
+        UriBuilder builder = UriBuilder.fromUri("http://10.0.10.13").port(9997);
+        this.graphDBhandler = new ClientsHandler(builder.build());
 
-	/**
-	 * retrieve resources dependent by type. determines based on the user's
-	 * permission or resource owner if the user can access the resource.
-	 * 
-	 * @param locale
-	 * @param context
-	 * @param type
-	 * @return valid resources in json format
-	 */
-	@GET
-	@Path("{type}")
-	public Response getResources(@Context Locale locale, @Context SecurityContext context,
-			@PathParam("type") String type) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		Set<KustvaktResource> resources = new HashSet<>();
-		type = StringUtils.normalize(type);
+        this.processor = new RewriteHandler();
+        this.processor.defaultRewriteConstraints();
+        this.processor.insertBeans(BeansFactory.getKustvaktContext());
+    }
 
-		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());
+    /**
+     * retrieve resources dependent by type. determines based on the
+     * user's
+     * permission or resource owner if the user can access the
+     * resource.
+     * 
+     * @param locale
+     * @param context
+     * @param type
+     * @return valid resources in json format
+     */
+    @GET
+    @Path("{type}")
+    public Response getResources (@Context Locale locale,
+            @Context SecurityContext context, @PathParam("type") String type) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        Set<KustvaktResource> resources = new HashSet<>();
+        type = StringUtils.normalize(type);
 
-			resources = ResourceFinder.search(user, ResourceFactory.getResourceClass(type));
-		} catch (KustvaktException e) {
-			throw KustvaktResponseHandler.throwit(e);
-		}
+        try {
+            Class cl_type = ResourceFactory.getResourceClass(type);
+            if (cl_type == null)
+                throw KustvaktResponseHandler.throwit(
+                        StatusCodes.MISSING_ARGUMENT,
+                        "Resource type not available!", "");
 
-		Set values = new HashSet();
-		for (KustvaktResource resource : resources)
-			values.add(resource.toMap());
-		return Response.ok(JsonUtils.toJSON(values)).build();
-	}
+            User user = controller.getUser(ctx.getUsername());
 
-	@GET
-	@Path("{type}/{id}/{child}")
-	public Response getResource(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @PathParam("id") String id, @PathParam("child") String child) {
-		return getResource(context, locale, type, StringUtils.joinResources(id, child));
-	}
+            resources = ResourceFinder.search(user,
+                    ResourceFactory.getResourceClass(type));
+        }
+        catch (KustvaktException e) {
+            throw KustvaktResponseHandler.throwit(e);
+        }
 
-	/**
-	 * @param context
-	 * @param locale
-	 * @param id
-	 * @param type
-	 * @return
-	 */
-	@GET
-	@Path("{type}/{id}")
-	public Response getResource(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @PathParam("id") String id) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		type = StringUtils.normalize(type);
-		KustvaktResource resource;
-		try {
-			Class cl_type = ResourceFactory.getResourceClass(type);
+        Set values = new HashSet();
+        for (KustvaktResource resource : resources)
+            values.add(resource.toMap());
+        return Response.ok(JsonUtils.toJSON(values)).build();
+    }
 
-			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 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();
-	}
+    @GET
+    @Path("{type}/{id}/{child}")
+    public Response getResource (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("child") String child) {
+        return getResource(context, locale, type,
+                StringUtils.joinResources(id, child));
+    }
 
-	// @GET
-	// @Path("colloc")
-	// public Response getCollocationsAll(@Context SecurityContext ctx,
-	// @Context Locale locale, @QueryParam("props") String properties,
-	// @QueryParam("sfskip") Integer sfs,
-	// @QueryParam("sflimit") Integer limit, @QueryParam("q") String query,
-	// @QueryParam("ql") String ql, @QueryParam("context") Integer context,
-	// @QueryParam("foundry") String foundry,
-	// @QueryParam("paths") Boolean wPaths) {
-	// TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
-	// ColloQuery.ColloQueryBuilder builder;
-	// KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
-	// String result;
-	// try {
-	// User user = controller.getUser(tokenContext.getUsername());
-	// Set<VirtualCollection> resources = ResourceFinder
-	// .search(user, VirtualCollection.class);
-	// for (KustvaktResource c : resources)
-	// cquery.addResource(((VirtualCollection) c).getQuery());
-	//
-	// builder = functions
-	// .buildCollocations(query, ql, properties, context, limit,
-	// sfs, foundry, new ArrayList<Dependency>(), wPaths,
-	// cquery);
-	//
-	// result = graphDBhandler
-	// .getResponse("distCollo", "q", builder.build().toJSON());
-	// }catch (KustvaktException e) {
-	// throw KustvaktResponseHandler.throwit(e);
-	// }catch (JsonProcessingException e) {
-	// throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
-	// }
-	// return Response.ok(result).build();
-	// }
 
-	// /**
-	// * @param locale
-	// * @param properties a json object string containing field, op and value
-	// for the query
-	// * @param query
-	// * @param context
-	// * @return
-	// */
-	// @GET
-	// @Path("{type}/{id}/colloc")
-	// public Response getCollocations(@Context SecurityContext ctx,
-	// @Context Locale locale, @QueryParam("props") String properties,
-	// @QueryParam("sfskip") Integer sfs,
-	// @QueryParam("sflimit") Integer limit, @QueryParam("q") String query,
-	// @QueryParam("ql") String ql, @QueryParam("context") Integer context,
-	// @QueryParam("foundry") String foundry,
-	// @QueryParam("paths") Boolean wPaths, @PathParam("id") String id,
-	// @PathParam("type") String type) {
-	// ColloQuery.ColloQueryBuilder builder;
-	// type = StringUtils.normalize(type);
-	// id = StringUtils.decodeHTML(id);
-	// TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
-	// String result;
-	// try {
-	// KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
-	// try {
-	// User user = controller.getUser(tokenContext.getUsername());
-	//
-	// KustvaktResource resource = this.resourceHandler
-	// .findbyStrId(id, user, type);
-	//
-	// if (resource instanceof VirtualCollection)
-	// cquery.addResource(
-	// ((VirtualCollection) resource).getQuery());
-	// else if (resource instanceof Corpus)
-	// cquery.addMetaFilter("corpusID",
-	// resource.getPersistentID());
-	// else
-	// throw KustvaktResponseHandler
-	// .throwit(StatusCodes.ILLEGAL_ARGUMENT,
-	// "Type parameter not supported", type);
-	//
-	// }catch (KustvaktException e) {
-	// throw KustvaktResponseHandler.throwit(e);
-	// }catch (NumberFormatException ex) {
-	// throw KustvaktResponseHandler
-	// .throwit(StatusCodes.ILLEGAL_ARGUMENT);
-	// }
-	//
-	// builder = functions
-	// .buildCollocations(query, ql, properties, context, limit,
-	// sfs, foundry, new ArrayList<Dependency>(), wPaths,
-	// cquery);
-	//
-	// result = graphDBhandler
-	// .getResponse("distCollo", "q", builder.build().toJSON());
-	//
-	// }catch (JsonProcessingException e) {
-	// throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
-	// }catch (KustvaktException e) {
-	// throw KustvaktResponseHandler.throwit(e);
-	// }
-	//
-	// return Response.ok(result).build();
-	// }
-	@POST
-	@Path("colloc")
-	public Response getCollocationBase(@QueryParam("q") String query) {
-		String result;
-		try {
-			result = graphDBhandler.getResponse("distCollo", "q", query);
-		} catch (KustvaktException e) {
-			throw KustvaktResponseHandler.throwit(e);
-		}
-		return Response.ok(result).build();
-	}
+    /**
+     * @param context
+     * @param locale
+     * @param id
+     * @param type
+     * @return
+     */
+    @GET
+    @Path("{type}/{id}")
+    public Response getResource (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        type = StringUtils.normalize(type);
+        KustvaktResource resource;
+        try {
+            Class cl_type = ResourceFactory.getResourceClass(type);
 
-	@Deprecated
-	public Response postMatchFavorite() {
-		return Response.ok().build();
-	}
+            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 e) {
+            // if (e.getStatusCode() != StatusCodes.ACCESS_DENIED)
+            throw KustvaktResponseHandler.throwit(e);
 
-	// ref query parameter removed!
-	@TRACE
-	@Path("search")
-	public Response buildQuery(@Context Locale locale, @Context SecurityContext securityContext,
-			@QueryParam("q") String q, @QueryParam("ql") String ql, @QueryParam("v") String v,
-			@QueryParam("context") String context, @QueryParam("cutoff") Boolean cutoff,
-			@QueryParam("count") Integer pageLength, @QueryParam("offset") Integer pageIndex,
-			@QueryParam("page") Integer startPage, @QueryParam("cq") String cq) {
-		TokenContext ctx = (TokenContext) securityContext.getUserPrincipal();
-		QuerySerializer ss;
+            // 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();
+    }
 
-		// User user;
-		// try {
-		// user = controller.getUser(ctx.getUsername());
-		// }
-		// catch (KustvaktException e) {
-		// throw KustvaktResponseHandler.throwit(e);
-		// }
+    // @GET
+    // @Path("colloc")
+    // public Response getCollocationsAll(@Context SecurityContext ctx,
+    // @Context Locale locale, @QueryParam("props") String properties,
+    // @QueryParam("sfskip") Integer sfs,
+    // @QueryParam("sflimit") Integer limit, @QueryParam("q") String query,
+    // @QueryParam("ql") String ql, @QueryParam("context") Integer context,
+    // @QueryParam("foundry") String foundry,
+    // @QueryParam("paths") Boolean wPaths) {
+    // TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
+    // ColloQuery.ColloQueryBuilder builder;
+    // KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
+    // String result;
+    // try {
+    // User user = controller.getUser(tokenContext.getUsername());
+    // Set<VirtualCollection> resources = ResourceFinder
+    // .search(user, VirtualCollection.class);
+    // for (KustvaktResource c : resources)
+    // cquery.addResource(((VirtualCollection) c).getQuery());
+    //
+    // builder = functions
+    // .buildCollocations(query, ql, properties, context, limit,
+    // sfs, foundry, new ArrayList<Dependency>(), wPaths,
+    // cquery);
+    //
+    // result = graphDBhandler
+    // .getResponse("distCollo", "q", builder.build().toJSON());
+    // }catch (KustvaktException e) {
+    // throw KustvaktResponseHandler.throwit(e);
+    // }catch (JsonProcessingException e) {
+    // throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
+    // }
+    // return Response.ok(result).build();
+    // }
 
-		ss = new QuerySerializer().setQuery(q, ql, v);
-		if (cq != null)
-			ss.setCollection(cq);
 
-		MetaQueryBuilder meta = new MetaQueryBuilder();
-		if (pageIndex != null)
-			meta.addEntry("startIndex", pageIndex);
-		if (pageIndex == null && startPage != null)
-			meta.addEntry("startPage", startPage);
-		if (pageLength != null)
-			meta.addEntry("count", pageLength);
-		if (context != null)
-			meta.setSpanContext(context);
-		meta.addEntry("cutOff", cutoff);
+    // /**
+    // * @param locale
+    // * @param properties a json object string containing field, op and value
+    // for the query
+    // * @param query
+    // * @param context
+    // * @return
+    // */
+    // @GET
+    // @Path("{type}/{id}/colloc")
+    // public Response getCollocations(@Context SecurityContext ctx,
+    // @Context Locale locale, @QueryParam("props") String properties,
+    // @QueryParam("sfskip") Integer sfs,
+    // @QueryParam("sflimit") Integer limit, @QueryParam("q") String query,
+    // @QueryParam("ql") String ql, @QueryParam("context") Integer context,
+    // @QueryParam("foundry") String foundry,
+    // @QueryParam("paths") Boolean wPaths, @PathParam("id") String id,
+    // @PathParam("type") String type) {
+    // ColloQuery.ColloQueryBuilder builder;
+    // type = StringUtils.normalize(type);
+    // id = StringUtils.decodeHTML(id);
+    // TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
+    // String result;
+    // try {
+    // KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
+    // try {
+    // User user = controller.getUser(tokenContext.getUsername());
+    //
+    // KustvaktResource resource = this.resourceHandler
+    // .findbyStrId(id, user, type);
+    //
+    // if (resource instanceof VirtualCollection)
+    // cquery.addResource(
+    // ((VirtualCollection) resource).getQuery());
+    // else if (resource instanceof Corpus)
+    // cquery.addMetaFilter("corpusID",
+    // resource.getPersistentID());
+    // else
+    // throw KustvaktResponseHandler
+    // .throwit(StatusCodes.ILLEGAL_ARGUMENT,
+    // "Type parameter not supported", type);
+    //
+    // }catch (KustvaktException e) {
+    // throw KustvaktResponseHandler.throwit(e);
+    // }catch (NumberFormatException ex) {
+    // throw KustvaktResponseHandler
+    // .throwit(StatusCodes.ILLEGAL_ARGUMENT);
+    // }
+    //
+    // builder = functions
+    // .buildCollocations(query, ql, properties, context, limit,
+    // sfs, foundry, new ArrayList<Dependency>(), wPaths,
+    // cquery);
+    //
+    // result = graphDBhandler
+    // .getResponse("distCollo", "q", builder.build().toJSON());
+    //
+    // }catch (JsonProcessingException e) {
+    // throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
+    // }catch (KustvaktException e) {
+    // throw KustvaktResponseHandler.throwit(e);
+    // }
+    //
+    // return Response.ok(result).build();
+    // }
+    @POST
+    @Path("colloc")
+    public Response getCollocationBase (@QueryParam("q") String query) {
+        String result;
+        try {
+            result = graphDBhandler.getResponse("distCollo", "q", query);
+        }
+        catch (KustvaktException e) {
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok(result).build();
+    }
 
-		ss.setMeta(meta.raw());
-		return Response.ok(ss.toJSON()).build();
-	}
 
-	/**
-	 * currently only supports either no reference at all in which case all
-	 * corpora are retrieved or a corpus name like "WPD". No virtual collections
-	 * supported!
-	 * 
-	 * @param locale
-	 * @param q
-	 * @param ql
-	 * @param v
-	 * @param pageLength
-	 * @param pageIndex
-	 * @return
-	 */
+    @Deprecated
+    public Response postMatchFavorite () {
+        return Response.ok().build();
+    }
 
-	// todo: does cq have any sensible worth here? --> would say no! --> is
-	// useful in non type/id scenarios
-	@TRACE
-	@Path("{type}/{id}/search")
-	public Response buildQueryWithId(@Context Locale locale, @Context SecurityContext securityContext,
-			@QueryParam("q") String q, @QueryParam("ql") String ql, @QueryParam("v") String v,
-			@QueryParam("context") String context, @QueryParam("cutoff") Boolean cutoff,
-			@QueryParam("count") Integer pageLength, @QueryParam("offset") Integer pageIndex,
-			@QueryParam("page") Integer startPage, @PathParam("type") String type, @PathParam("id") String id) {
-		TokenContext ctx = (TokenContext) securityContext.getUserPrincipal();
-		type = StringUtils.normalize(type);
-		id = StringUtils.decodeHTML(id);
 
-		QuerySerializer ss = new QuerySerializer().setQuery(q, ql, v);
+    // ref query parameter removed!
+    @TRACE
+    @Path("search")
+    public Response buildQuery (@Context Locale locale,
+            @Context SecurityContext securityContext, @QueryParam("q") String q,
+            @QueryParam("ql") String ql, @QueryParam("v") String v,
+            @QueryParam("context") String context,
+            @QueryParam("cutoff") Boolean cutoff,
+            @QueryParam("count") Integer pageLength,
+            @QueryParam("offset") Integer pageIndex,
+            @QueryParam("page") Integer startPage,
+            @QueryParam("cq") String cq) {
+        TokenContext ctx = (TokenContext) securityContext.getUserPrincipal();
+        QuerySerializer ss;
 
-		MetaQueryBuilder meta = new MetaQueryBuilder();
-		if (pageIndex != null)
-			meta.addEntry("startIndex", pageIndex);
-		if (pageIndex == null && startPage != null)
-			meta.addEntry("startPage", startPage);
-		if (pageLength != null)
-			meta.addEntry("count", pageLength);
-		if (context != null)
-			meta.setSpanContext(context);
-		if (cutoff != null)
-			meta.addEntry("cutOff", cutoff);
+        // User user;
+        // try {
+        // user = controller.getUser(ctx.getUsername());
+        // }
+        // catch (KustvaktException e) {
+        // throw KustvaktResponseHandler.throwit(e);
+        // }
 
-		ss.setMeta(meta.raw());
+        ss = new QuerySerializer().setQuery(q, ql, v);
+        if (cq != null)
+            ss.setCollection(cq);
 
-		KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
-		cquery.setBaseQuery(ss.toJSON());
+        MetaQueryBuilder meta = new MetaQueryBuilder();
+        if (pageIndex != null)
+            meta.addEntry("startIndex", pageIndex);
+        if (pageIndex == null && startPage != null)
+            meta.addEntry("startPage", startPage);
+        if (pageLength != null)
+            meta.addEntry("count", pageLength);
+        if (context != null)
+            meta.setSpanContext(context);
+        meta.addEntry("cutOff", cutoff);
 
-		String query = "";
-		KustvaktResource resource;
-		try {
+        ss.setMeta(meta.raw());
+        return Response.ok(ss.toJSON()).build();
+    }
 
-			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));
-			}
-		}
-		// 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) {
-			if (resource instanceof VirtualCollection)
-				query = JsonUtils.toJSON(cquery.and().mergeWith(resource.getData()));
-			else if (resource instanceof Corpus) {
-				cquery.and().with(Attributes.CORPUS_SIGLE, "=", resource.getPersistentID());
-				query = cquery.toJSON();
-			}
-		}
-		return Response.ok(query).build();
-	}
+    /**
+     * currently only supports either no reference at all in which
+     * case all
+     * corpora are retrieved or a corpus name like "WPD". No virtual
+     * collections
+     * supported!
+     * 
+     * @param locale
+     * @param q
+     * @param ql
+     * @param v
+     * @param pageLength
+     * @param pageIndex
+     * @return
+     */
 
-	@POST
-	@Path("search")
-	public Response queryRaw(@Context SecurityContext context, @Context Locale locale,
-			@QueryParam("engine") String engine, String jsonld) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
+    // todo: does cq have any sensible worth here? --> would say no! --> is
+    // useful in non type/id scenarios
+    @TRACE
+    @Path("{type}/{id}/search")
+    public Response buildQueryWithId (@Context Locale locale,
+            @Context SecurityContext securityContext, @QueryParam("q") String q,
+            @QueryParam("ql") String ql, @QueryParam("v") String v,
+            @QueryParam("context") String context,
+            @QueryParam("cutoff") Boolean cutoff,
+            @QueryParam("count") Integer pageLength,
+            @QueryParam("offset") Integer pageIndex,
+            @QueryParam("page") Integer startPage,
+            @PathParam("type") String type, @PathParam("id") String id) {
+        TokenContext ctx = (TokenContext) securityContext.getUserPrincipal();
+        type = StringUtils.normalize(type);
+        id = StringUtils.decodeHTML(id);
 
-		// todo: should be possible to add the meta part to the query
-		// serialization
-		try {
-			User user = controller.getUser(ctx.getUsername());
-			// jsonld = this.processor.processQuery(jsonld, user);
-		} catch (KustvaktException e) {
-			throw KustvaktResponseHandler.throwit(e);
-		}
-		jlog.info("Serialized search: {}", jsonld);
+        QuerySerializer ss = new QuerySerializer().setQuery(q, ql, v);
 
-		String result = searchKrill.search(jsonld);
-		// todo: logging
-		KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
-		return Response.ok(result).build();
-	}
+        MetaQueryBuilder meta = new MetaQueryBuilder();
+        if (pageIndex != null)
+            meta.addEntry("startIndex", pageIndex);
+        if (pageIndex == null && startPage != null)
+            meta.addEntry("startPage", startPage);
+        if (pageLength != null)
+            meta.addEntry("count", pageLength);
+        if (context != null)
+            meta.setSpanContext(context);
+        if (cutoff != null)
+            meta.addEntry("cutOff", cutoff);
 
-	@GET
-	@Path("search")
-	public Response searchbyNameAll(@Context SecurityContext securityContext, @Context Locale locale,
-			@QueryParam("q") String q, @QueryParam("ql") String ql, @QueryParam("v") String v,
-			@QueryParam("context") String ctx, @QueryParam("cutoff") Boolean cutoff,
-			@QueryParam("count") Integer pageLength, @QueryParam("offset") Integer pageIndex,
-			@QueryParam("page") Integer pageInteger, @QueryParam("cq") String cq, @QueryParam("engine") String engine) {
-		TokenContext context = (TokenContext) securityContext.getUserPrincipal();
-		KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
-		User user;
-		try {
-			user = controller.getUser(context.getUsername());
-		} catch (KustvaktException e) {
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
-		String result;
-		QuerySerializer serializer = new QuerySerializer();
-		serializer.setQuery(q, ql, v);
+        ss.setMeta(meta.raw());
 
-		if (cq != null)
-			serializer.setCollection(cq);
+        KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
+        cquery.setBaseQuery(ss.toJSON());
 
-		MetaQueryBuilder meta = new MetaQueryBuilder();
-		meta.addEntry("startIndex", pageIndex);
-		meta.addEntry("startPage", pageInteger);
-		meta.setSpanContext(ctx);
-		meta.addEntry("count", pageLength);
-		// todo: what happened to cutoff?
-		meta.addEntry("cutoff", cutoff);
-		// meta.addMeta(pageIndex, pageInteger, pageLength, ctx, cutoff);
-		// fixme: should only apply to CQL queries per default!
-		// meta.addEntry("itemsPerResource", 1);
-		serializer.setMeta(meta.raw());
-		String query;
-		try {
-			query = this.processor.processQuery(serializer.toJSON(), user);
-		} catch (KustvaktException e) {
-			throw KustvaktResponseHandler.throwit(e);
-		}
+        String query = "";
+        KustvaktResource resource;
+        try {
 
-		jlog.info("the serialized query {}", query);
+            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));
+            }
+        }
+        // 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 (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
-			MultivaluedMap map = new MultivaluedMapImpl();
-			map.add("q", query);
-			map.add("count", String.valueOf(pageLength));
-			map.add("lctxs", String.valueOf(meta.getSpanContext().getLeftSize()));
-			map.add("rctxs", String.valueOf(meta.getSpanContext().getRightSize()));
-			try {
-				result = this.graphDBhandler.getResponse(map, "distKwic");
-			} catch (KustvaktException e) {
-				jlog.error("Exception encountered: {}", e.string());
-				throw KustvaktResponseHandler.throwit(e);
-			}
-		} else
-			result = searchKrill.search(query);
-		KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
-		return Response.ok(result).build();
-	}
+        if (resource != null) {
+            if (resource instanceof VirtualCollection)
+                query = JsonUtils
+                        .toJSON(cquery.and().mergeWith(resource.getData()));
+            else if (resource instanceof Corpus) {
+                cquery.and().with(Attributes.CORPUS_SIGLE, "=",
+                        resource.getPersistentID());
+                query = cquery.toJSON();
+            }
+        }
+        return Response.ok(query).build();
+    }
+
+
+    @POST
+    @Path("search")
+    public Response queryRaw (@Context SecurityContext context,
+            @Context Locale locale, @QueryParam("engine") String engine,
+            String jsonld) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+
+        // todo: should be possible to add the meta part to the query
+        // serialization
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            // jsonld = this.processor.processQuery(jsonld, user);
+        }
+        catch (KustvaktException e) {
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        jlog.info("Serialized search: {}", jsonld);
+
+        String result = searchKrill.search(jsonld);
+        // todo: logging
+        KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
+        return Response.ok(result).build();
+    }
+
+
+    @GET
+    @Path("search")
+    public Response searchbyNameAll (@Context SecurityContext securityContext,
+            @Context Locale locale, @QueryParam("q") String q,
+            @QueryParam("ql") String ql, @QueryParam("v") String v,
+            @QueryParam("context") String ctx,
+            @QueryParam("cutoff") Boolean cutoff,
+            @QueryParam("count") Integer pageLength,
+            @QueryParam("offset") Integer pageIndex,
+            @QueryParam("page") Integer pageInteger,
+            @QueryParam("cq") String cq, @QueryParam("engine") String engine) {
+        TokenContext context = (TokenContext) securityContext
+                .getUserPrincipal();
+        KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
+        User user;
+        try {
+            user = controller.getUser(context.getUsername());
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        String result;
+        QuerySerializer serializer = new QuerySerializer();
+        serializer.setQuery(q, ql, v);
+
+        if (cq != null)
+            serializer.setCollection(cq);
+
+        MetaQueryBuilder meta = new MetaQueryBuilder();
+        meta.addEntry("startIndex", pageIndex);
+        meta.addEntry("startPage", pageInteger);
+        meta.setSpanContext(ctx);
+        meta.addEntry("count", pageLength);
+        // todo: what happened to cutoff?
+        meta.addEntry("cutoff", cutoff);
+        // meta.addMeta(pageIndex, pageInteger, pageLength, ctx, cutoff);
+        // fixme: should only apply to CQL queries per default!
+        // meta.addEntry("itemsPerResource", 1);
+        serializer.setMeta(meta.raw());
+        String query;
+        try {
+            query = this.processor.processQuery(serializer.toJSON(), user);
+        }
+        catch (KustvaktException e) {
+            throw KustvaktResponseHandler.throwit(e);
+        }
+
+        jlog.info("the serialized query {}", query);
+
+        if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
+            MultivaluedMap map = new MultivaluedMapImpl();
+            map.add("q", query);
+            map.add("count", String.valueOf(pageLength));
+            map.add("lctxs",
+                    String.valueOf(meta.getSpanContext().getLeftSize()));
+            map.add("rctxs",
+                    String.valueOf(meta.getSpanContext().getRightSize()));
+            try {
+                result = this.graphDBhandler.getResponse(map, "distKwic");
+            }
+            catch (KustvaktException e) {
+                jlog.error("Exception encountered: {}", e.string());
+                throw KustvaktResponseHandler.throwit(e);
+            }
+        }
+        else
+            result = searchKrill.search(query);
+        KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
+        return Response.ok(result).build();
+    }
+
+
+    /**
+     * String search, String ql, List<String> parents, String cli,
+     * String cri,
+     * int cls, int crs, int num, int page, boolean cutoff) param
+     * context will
+     * be like this: context: "3-t,2-c"
+     * <p/>
+     * id does not have to be an integer. name is also possible, in
+     * which case a
+     * type reference is required
+     * 
+     * @param securityContext
+     * @param locale
+     * @return
+     */
+    // todo: remove raw
+    @GET
+    @Path("/{type}/{id}/search")
+    public Response searchbyName (@Context SecurityContext securityContext,
+            @Context Locale locale, @QueryParam("q") String query,
+            @QueryParam("ql") String ql, @QueryParam("v") String v,
+            @QueryParam("context") String ctx,
+            @QueryParam("cutoff") Boolean cutoff,
+            @QueryParam("count") Integer pageLength,
+            @QueryParam("offset") Integer pageIndex,
+            @QueryParam("page") Integer pageInteger, @PathParam("id") String id,
+            @PathParam("type") String type, @QueryParam("cq") String cq,
+            @QueryParam("raw") Boolean raw,
+            @QueryParam("engine") String engine) {
+        // ref is a virtual collection id!
+        TokenContext context = (TokenContext) securityContext
+                .getUserPrincipal();
+        KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
+        type = StringUtils.normalize(type);
+        id = StringUtils.decodeHTML(id);
+        raw = raw == null ? false : raw;
+
+        try {
+            User user = controller.getUser(context.getUsername());
+            MetaQueryBuilder meta = new MetaQueryBuilder();
+
+            if (!raw) {
+                QuerySerializer s = new QuerySerializer();
+                s.setQuery(query, ql, v);
+
+                KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+
+                KustvaktResource resource;
+                if (StringUtils.isInteger(id))
+                    resource = this.resourceHandler
+                            .findbyIntId(Integer.valueOf(id), user);
+                else
+                    resource = this.resourceHandler.findbyStrId(id, user,
+                            ResourceFactory.getResourceClass(type));
+
+                if (resource instanceof VirtualCollection)
+                    builder.setBaseQuery(resource.getData());
+                else if (resource instanceof Corpus)
+                    builder.with(Attributes.CORPUS_SIGLE
+                            + resource.getPersistentID());
+                else
+                    throw KustvaktResponseHandler.throwit(
+                            StatusCodes.ILLEGAL_ARGUMENT,
+                            "Type parameter not supported", type);
+
+                meta.addEntry("startIndex", pageIndex);
+                meta.addEntry("startPage", pageInteger);
+                meta.setSpanContext(ctx);
+                meta.addEntry("count", pageLength);
+                // todo: what happened to cutoff?
+                meta.addEntry("cutoff", cutoff);
+                // should only apply to CQL queries
+                // meta.addEntry("itemsPerResource", 1);
+                s.setMeta(meta.raw());
+
+                query = s.toJSON();
+            }
+            String result;
+            try {
+
+                // rewrite process
+                query = this.processor.processQuery(query, user);
+
+                if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
+                    if (raw)
+                        throw KustvaktResponseHandler.throwit(
+                                StatusCodes.ILLEGAL_ARGUMENT,
+                                "raw not supported!", null);
+                    MultivaluedMap map = new MultivaluedMapImpl();
+                    map.add("q", query);
+                    map.add("count", String.valueOf(pageLength));
+                    map.add("lctxs", String
+                            .valueOf(meta.getSpanContext().getLeftSize()));
+                    map.add("rctxs", String
+                            .valueOf(meta.getSpanContext().getRightSize()));
+                    result = this.graphDBhandler.getResponse(map, "distKwic");
+                }
+                else
+                    result = searchKrill.search(query);
+
+            }
+            catch (Exception e) {
+                jlog.error("Exception for serialized query: " + query, e);
+                throw KustvaktResponseHandler.throwit(500, e.getMessage(),
+                        null);
+            }
+
+            KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
+            return Response.ok(result).build();
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
+
+    }
+
+
+    @POST
+    @Path("stats")
+    public Response getStats (@Context SecurityContext context,
+            @Context Locale locale, String json) {
+        KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+        builder.with(json);
+        String stats = searchKrill.getStatistics(builder.toJSON());
+
+        if (stats.contains("-1"))
+            throw KustvaktResponseHandler.throwit(StatusCodes.NO_VALUE_FOUND);
+
+        return Response.ok(stats).build();
+    }
+
 
-	/**
-	 * String search, String ql, List<String> parents, String cli, String cri,
-	 * int cls, int crs, int num, int page, boolean cutoff) param context will
-	 * be like this: context: "3-t,2-c"
-	 * <p/>
-	 * id does not have to be an integer. name is also possible, in which case a
-	 * type reference is required
-	 * 
-	 * @param securityContext
-	 * @param locale
-	 * @return
-	 */
-	// todo: remove raw
-	@GET
-	@Path("/{type}/{id}/search")
-	public Response searchbyName(@Context SecurityContext securityContext, @Context Locale locale,
-			@QueryParam("q") String query, @QueryParam("ql") String ql, @QueryParam("v") String v,
-			@QueryParam("context") String ctx, @QueryParam("cutoff") Boolean cutoff,
-			@QueryParam("count") Integer pageLength, @QueryParam("offset") Integer pageIndex,
-			@QueryParam("page") Integer pageInteger, @PathParam("id") String id, @PathParam("type") String type,
-			@QueryParam("cq") String cq, @QueryParam("raw") Boolean raw, @QueryParam("engine") String engine) {
-		// ref is a virtual collection id!
-		TokenContext context = (TokenContext) securityContext.getUserPrincipal();
-		KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
-		type = StringUtils.normalize(type);
-		id = StringUtils.decodeHTML(id);
-		raw = raw == null ? false : raw;
+    @GET
+    @Path("{type}/{id}/{child}/stats")
+    public Response getStatisticsbyIdChild (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("child") String child) {
+        return getStatisticsbyId(context, locale, type,
+                StringUtils.joinResources(id, child));
+    }
 
-		try {
-			User user = controller.getUser(context.getUsername());
-			MetaQueryBuilder meta = new MetaQueryBuilder();
 
-			if (!raw) {
-				QuerySerializer s = new QuerySerializer();
-				s.setQuery(query, ql, v);
+    @GET
+    @Path("{type}/{id}/stats")
+    public Response getStatisticsbyId (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        type = StringUtils.normalize(type);
+        id = StringUtils.decodeHTML(id);
 
-				KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+        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);
 
-				KustvaktResource resource;
-				if (StringUtils.isInteger(id))
-					resource = this.resourceHandler.findbyIntId(Integer.valueOf(id), user);
-				else
-					resource = this.resourceHandler.findbyStrId(id, user, ResourceFactory.getResourceClass(type));
+            User user = controller.getUser(ctx.getUsername());
+            KustvaktResource resource;
+            if (StringUtils.isInteger(id))
+                resource = this.resourceHandler.findbyIntId(Integer.valueOf(id),
+                        user);
+            else
+                resource = this.resourceHandler.findbyStrId(id, user,
+                        ResourceFactory.getResourceClass(type));
 
-				if (resource instanceof VirtualCollection)
-					builder.setBaseQuery(resource.getData());
-				else if (resource instanceof Corpus)
-					builder.with(Attributes.CORPUS_SIGLE + resource.getPersistentID());
-				else
-					throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT, "Type parameter not supported",
-							type);
+            // todo ?!
+            KoralCollectionQueryBuilder query = new KoralCollectionQueryBuilder();
+            if (resource instanceof VirtualCollection) {
+                query.setBaseQuery(resource.getData());
+            }
+            else if (resource instanceof Corpus) {
+                query.with(Attributes.CORPUS_SIGLE + "=" + resource.getName());
+            }
+            String res = query.toJSON();
+            String qstr = processor.processQuery(res, user);
+            return Response.ok(searchKrill.getStatistics(qstr)).build();
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
+    }
 
-				meta.addEntry("startIndex", pageIndex);
-				meta.addEntry("startPage", pageInteger);
-				meta.setSpanContext(ctx);
-				meta.addEntry("count", pageLength);
-				// todo: what happened to cutoff?
-				meta.addEntry("cutoff", cutoff);
-				// should only apply to CQL queries
-				// meta.addEntry("itemsPerResource", 1);
-				s.setMeta(meta.raw());
 
-				query = s.toJSON();
-			}
-			String result;
-			try {
+    /**
+     * @param context
+     * @param locale
+     * @param json
+     * @return
+     */
+    // todo: rename
+    @POST
+    @Path("collection_raw")
+    public Response createRawCollection (@Context SecurityContext context,
+            @Context Locale locale, String json) {
+        TokenContext c = (TokenContext) context.getUserPrincipal();
+        VirtualCollection cache = ResourceFactory.getCachedCollection(json);
+        User user;
+        try {
+            user = controller.getUser(c.getUsername());
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
 
-				// rewrite process
-				query = this.processor.processQuery(query, user);
+        VirtualCollection tmp = resourceHandler.getCache(cache.getId(),
+                VirtualCollection.class);
+        if (tmp == null) {
+            String query;
+            try {
+                query = this.processor.processQuery(cache.getData(), user);
+            }
+            catch (KustvaktException e) {
+                throw KustvaktResponseHandler.throwit(e);
+            }
+            String stats = searchKrill.getStatistics(query);
+            cache.setStats(JsonUtils.readSimple(stats, Map.class));
+            resourceHandler.cache(cache);
+        }
+        else
+            cache = tmp;
 
-				if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
-					if (raw)
-						throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT, "raw not supported!", null);
-					MultivaluedMap map = new MultivaluedMapImpl();
-					map.add("q", query);
-					map.add("count", String.valueOf(pageLength));
-					map.add("lctxs", String.valueOf(meta.getSpanContext().getLeftSize()));
-					map.add("rctxs", String.valueOf(meta.getSpanContext().getRightSize()));
-					result = this.graphDBhandler.getResponse(map, "distKwic");
-				} else
-					result = searchKrill.search(query);
+        Map vals = new HashMap();
+        vals.put("id", cache.getId());
+        vals.put("statistics", cache.getStats());
+        return Response.ok(JsonUtils.toJSON(vals)).build();
+    }
 
-			} catch (Exception e) {
-				jlog.error("Exception for serialized query: " + query, e);
-				throw KustvaktResponseHandler.throwit(500, e.getMessage(), null);
-			}
 
-			KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
-			return Response.ok(result).build();
-		} catch (KustvaktException e) {
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
+    @POST
+    @Path("{type}/{id}")
+    public Response updateResource (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id, @QueryParam("name") String name,
+            @QueryParam("description") String description) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        User user;
+        try {
+            user = controller.getUser(ctx.getUsername());
+            KustvaktResource resource = this.resourceHandler.findbyStrId(id,
+                    user, ResourceFactory.getResourceClass(type));
 
-	}
+            if (name != null && !name.isEmpty()) {
+                if (description == null) {
+                    if (name.equals(resource.getName())) {
+                        return Response.notModified("No change has found.")
+                                .build();
+                    }
+                }
+                else if (name.equals(resource.getName())
+                        && description.equals(resource.getDescription())) {
+                    return Response.notModified("No change has found.").build();
+                }
+                else {
+                    resource.setName(name);
+                }
+            }
+            else if (description != null && !description.isEmpty()) {
+                resource.setDescription(description);
+            }
+            else {
+                Response.notModified(
+                        "New name and description are not specified.").build();
+            }
 
-	@POST
-	@Path("stats")
-	public Response getStats(@Context SecurityContext context, @Context Locale locale, String json) {
-		KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
-		builder.with(json);
-		String stats = searchKrill.getStatistics(builder.toJSON());
 
-		if (stats.contains("-1"))
-			throw KustvaktResponseHandler.throwit(StatusCodes.NO_VALUE_FOUND);
+            this.resourceHandler.updateResources(user, resource);
+        }
+        catch (
 
-		return Response.ok(stats).build();
-	}
+        KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
 
-	@GET
-	@Path("{type}/{id}/{child}/stats")
-	public Response getStatisticsbyIdChild(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @PathParam("id") String id, @PathParam("child") String child) {
-		return getStatisticsbyId(context, locale, type, StringUtils.joinResources(id, child));
-	}
 
-	@GET
-	@Path("{type}/{id}/stats")
-	public Response getStatisticsbyId(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @PathParam("id") String id) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		type = StringUtils.normalize(type);
-		id = StringUtils.decodeHTML(id);
+    // todo: change or deprecate
+    @POST
+    @Path("nv/{type}")
+    public Response storeResource (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @QueryParam("name") String name,
+            @QueryParam("description") String description,
+            // deprecate -> if you want to store a resource based on another,
+            // build the query first yourself or via a function
+            @QueryParam("ref") String reference,
+            @QueryParam("cache") Boolean cache,
+            @QueryParam("query") String query) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        cache = cache != null ? cache : false;
+        type = StringUtils.normalize(type);
+        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(ctype)) {
+            VirtualCollection cachetmp, collection;
 
-		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);
+            JsonNode base;
+            if (reference != null && !reference.equals("null")) {
+                try {
+                    base = resourceHandler.findbyStrId(reference, user,
+                            VirtualCollection.class).getData();
+                }
+                catch (KustvaktException e) {
+                    throw KustvaktResponseHandler.throwit(e);
+                }
 
-			User user = controller.getUser(ctx.getUsername());
-			KustvaktResource resource;
-			if (StringUtils.isInteger(id))
-				resource = this.resourceHandler.findbyIntId(Integer.valueOf(id), user);
-			else
-				resource = this.resourceHandler.findbyStrId(id, user, ResourceFactory.getResourceClass(type));
+            }
+            else if (query != null)
+                base = JsonUtils.readTree(query);
+            else
+                // todo: throw exception response for no resource to save!
+                return null;
 
-			// todo ?!
-			KoralCollectionQueryBuilder query = new KoralCollectionQueryBuilder();
-			if (resource instanceof VirtualCollection) {
-				query.setBaseQuery(resource.getData());
-			} else if (resource instanceof Corpus) {
-				query.with(Attributes.CORPUS_SIGLE + "=" + resource.getName());
-			}
-			String res = query.toJSON();
-			String qstr = processor.processQuery(res, user);
-			return Response.ok(searchKrill.getStatistics(qstr)).build();
-		} catch (KustvaktException e) {
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
-	}
+            KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
+            cquery.setBaseQuery(base);
 
-	/**
-	 * @param context
-	 * @param locale
-	 * @param json
-	 * @return
-	 */
-	// todo: rename
-	@POST
-	@Path("collection_raw")
-	public Response createRawCollection(@Context SecurityContext context, @Context Locale locale, String json) {
-		TokenContext c = (TokenContext) context.getUserPrincipal();
-		VirtualCollection cache = ResourceFactory.getCachedCollection(json);
-		User user;
-		try {
-			user = controller.getUser(c.getUsername());
-		} catch (KustvaktException e) {
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
+            cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON());
 
-		VirtualCollection tmp = resourceHandler.getCache(cache.getId(), VirtualCollection.class);
-		if (tmp == null) {
-			String query;
-			try {
-				query = this.processor.processQuery(cache.getData(), user);
-			} catch (KustvaktException e) {
-				throw KustvaktResponseHandler.throwit(e);
-			}
-			String stats = searchKrill.getStatistics(query);
-			cache.setStats(JsonUtils.readSimple(stats, Map.class));
-			resourceHandler.cache(cache);
-		} else
-			cache = tmp;
+            // see if collection was cached!
+            VirtualCollection tmp = resourceHandler.getCache(cachetmp.getId(),
+                    VirtualCollection.class);
+            // if not cached, fill with stats values
+            if (tmp == null) {
+                String stats = searchKrill.getStatistics(cquery.toJSON());
+                cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
+            }
 
-		Map vals = new HashMap();
-		vals.put("id", cache.getId());
-		vals.put("statistics", cache.getStats());
-		return Response.ok(JsonUtils.toJSON(vals)).build();
-	}
+            if (!cache) {
+                collection = ResourceFactory.getPermanentCollection(cachetmp,
+                        name, description);
+                vals = collection.toMap();
+                try {
+                    resourceHandler.storeResources(user, collection);
+                }
+                catch (KustvaktException e) {
+                    jlog.error("Exception encountered: {}", e.string());
+                    throw KustvaktResponseHandler.throwit(e);
+                }
+            }
+            else {
+                resourceHandler.cache(cachetmp);
+                vals = cachetmp.toMap();
+            }
+        }
+        return Response.ok(JsonUtils.toJSON(vals)).build();
+    }
 
-	@POST
-	@Path("{type}/{id}")
-	public Response updateResource(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @PathParam("id") String id, String json) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		User user;
-		try {
-			user = controller.getUser(ctx.getUsername());
-			KustvaktResource resource = this.resourceHandler.findbyStrId(id, user,
-					ResourceFactory.getResourceClass(type));
-			JsonNode node = JsonUtils.readTree(json);
 
-			if (node.isObject() && !node.path("name").isMissingNode()) {
-				String s = node.path("name").asText();
-				if (s.equals("null") || s.isEmpty())
-					throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT, "Name must be set", "name");
-				resource.setName(s);
-			}
+    /**
+     * EM: store a virtual collection in a database, but
+     * /virtualcollection
+     * service (@see
+     * {@link #getResource(SecurityContext, Locale, String, String)})
+     * does not
+     * list it because the collection is not stored in the
+     * policy_store table as well.
+     * 
+     * Retrieve cached entry first and then store collection
+     * 
+     * @param context
+     * @param locale
+     * @param query
+     * @return
+     */
+    @POST
+    @Path("{type}")
+    public Response storeResource (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @QueryParam("filter") Boolean filter,
+            @QueryParam("name") String name,
+            @QueryParam("description") String description,
+            @QueryParam("ref") String reference,
+            @QueryParam("cache") Boolean cache, String query) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        filter = filter != null ? filter : false;
+        cache = cache != null ? cache : false;
+        type = StringUtils.normalize(type);
+        reference = StringUtils.decodeHTML(reference);
+        Map vals = new HashMap();
+        User user;
+        Class ctype;
+        try {
+            ctype = ResourceFactory.getResourceClass(type);
 
-			if (node.isObject() && !node.path("description").isMissingNode())
-				resource.setDescription(node.path("description").asText());
-			this.resourceHandler.updateResources(user, resource);
-		} catch (KustvaktException e) {
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
-		return Response.ok().build();
-	}
+            user = controller.getUser(ctx.getUsername());
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
 
-	// todo: change or deprecate
-	@POST
-	@Path("nv/{type}")
-	public Response storeResource(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @QueryParam("name") String name,
-			@QueryParam("description") String description,
-			// deprecate -> if you want to store a resource based on another,
-			// build the query first yourself or via a function
-			@QueryParam("ref") String reference, @QueryParam("cache") Boolean cache,
-			@QueryParam("query") String query) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		cache = cache != null ? cache : false;
-		type = StringUtils.normalize(type);
-		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(ctype)) {
-			VirtualCollection cachetmp, collection;
+        if (VirtualCollection.class.equals(ctype)) {
+            VirtualCollection cachetmp, collection;
 
-			JsonNode base;
-			if (reference != null && !reference.equals("null")) {
-				try {
-					base = resourceHandler.findbyStrId(reference, user, VirtualCollection.class).getData();
-				} catch (KustvaktException e) {
-					throw KustvaktResponseHandler.throwit(e);
-				}
+            KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
+            if (reference != null && !reference.equals("null")) {
+                try {
+                    cquery.setBaseQuery(resourceHandler.findbyStrId(reference,
+                            user, VirtualCollection.class).getData());
 
-			} else if (query != null)
-				base = JsonUtils.readTree(query);
-			else
-				// todo: throw exception response for no resource to save!
-				return null;
+                }
+                catch (KustvaktException e) {
+                    throw KustvaktResponseHandler.throwit(e);
+                }
+            }
+            if (query != null && !query.isEmpty())
+                cquery.with(query);
 
-			KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
-			cquery.setBaseQuery(base);
+            cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON());
 
-			cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON());
+            // see if vc was cached!
+            VirtualCollection tmp = resourceHandler.getCache(cachetmp.getId(),
+                    VirtualCollection.class);
 
-			// see if collection was cached!
-			VirtualCollection tmp = resourceHandler.getCache(cachetmp.getId(), VirtualCollection.class);
-			// if not cached, fill with stats values
-			if (tmp == null) {
-				String stats = searchKrill.getStatistics(cquery.toJSON());
-				cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
-			}
+            // if not cached, fill with stats values
+            if (tmp == null) {
+                String stats = searchKrill.getStatistics(cquery.toJSON());
+                cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
+                if (query != null && !query.isEmpty())
+                    cachetmp.setFields(cquery.toJSON());
+            }
 
-			if (!cache) {
-				collection = ResourceFactory.getPermanentCollection(cachetmp, name, description);
-				vals = collection.toMap();
-				try {
-					resourceHandler.storeResources(user, collection);
-				} catch (KustvaktException e) {
-					jlog.error("Exception encountered: {}", e.string());
-					throw KustvaktResponseHandler.throwit(e);
-				}
-			} else {
-				resourceHandler.cache(cachetmp);
-				vals = cachetmp.toMap();
-			}
-		}
-		return Response.ok(JsonUtils.toJSON(vals)).build();
-	}
+            if (!cache && !User.UserFactory.isDemo(ctx.getUsername())) {
+                collection = ResourceFactory.getPermanentCollection(cachetmp,
+                        name, description);
+                vals = collection.toMap();
+                try {
+                    resourceHandler.storeResources(user, collection);
+                }
+                catch (KustvaktException e) {
+                    jlog.error("Exception encountered: {}", e.string());
+                    throw KustvaktResponseHandler.throwit(e);
+                }
+            }
+            else {
+                resourceHandler.cache(cachetmp);
+                vals = cachetmp.toMap();
+            }
+        }
+        return Response.ok(JsonUtils.toJSON(vals)).build();
+    }
 
-	/**
-	 * EM: store a virtual collection in a database, but /virtualcollection
-	 * service (@see
-	 * {@link #getResource(SecurityContext, Locale, String, String)}) does not
-	 * list it because the collection is not stored in the policy_store table as well.
-	 * 
-	 * Retrieve cached entry first and then store collection
-	 * 
-	 * @param context
-	 * @param locale
-	 * @param query
-	 * @return
-	 */
-	// todo: testing
-	@POST
-	@Path("{type}")
-	public Response storeResource(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @QueryParam("filter") Boolean filter, @QueryParam("name") String name,
-			@QueryParam("description") String description, @QueryParam("ref") String reference,
-			@QueryParam("cache") Boolean cache, String query) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		filter = filter != null ? filter : false;
-		cache = cache != null ? cache : false;
-		type = StringUtils.normalize(type);
-		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);
-		}
+    @DELETE
+    @Path("{type}/{id}/{child}")
+    public Response deleteResourceChild (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("child") String child) {
+        return deleteResource(context, locale, type,
+                StringUtils.joinResources(id, child));
+    }
 
-		if (VirtualCollection.class.equals(ctype)) {
-			VirtualCollection cachetmp, collection;
 
-			KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
-			if (reference != null && !reference.equals("null")) {
-				try {
-					cquery.setBaseQuery(
-							resourceHandler.findbyStrId(reference, user, VirtualCollection.class).getData());
+    @DELETE
+    @Path("{type}/{id}")
+    public Response deleteResource (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        type = StringUtils.normalizeHTML(type);
+        id = StringUtils.decodeHTML(id);
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            KustvaktResource r = ResourceFactory.getResource(type);
+            r.setPersistentID(id);
+            // todo: eliminate the need to find the resource first!
+            resourceHandler.deleteResources(user, r);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
 
-				} catch (KustvaktException e) {
-					throw KustvaktResponseHandler.throwit(e);
-				}
-			}
-			if (query != null && !query.isEmpty())
-				cquery.with(query);
+        return Response.ok().build();
+    }
 
-			cachetmp = ResourceFactory.getCachedCollection(cquery.toJSON());
-			
-			// see if vc was cached!
-			VirtualCollection tmp = resourceHandler.getCache(cachetmp.getId(), VirtualCollection.class);
-			
-			// if not cached, fill with stats values
-			if (tmp == null) {
-				String stats = searchKrill.getStatistics(cquery.toJSON());
-				cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
-				if (query != null && !query.isEmpty())
-					cachetmp.setFields(cquery.toJSON());
-			}
-			
-			if (!cache && !User.UserFactory.isDemo(ctx.getUsername())) {
-				collection = ResourceFactory.getPermanentCollection(cachetmp, name, description);
-				vals = collection.toMap();
-				try {
-					resourceHandler.storeResources(user, collection);
-				} catch (KustvaktException e) {
-					jlog.error("Exception encountered: {}", e.string());
-					throw KustvaktResponseHandler.throwit(e);
-				}
-			} else {
-				resourceHandler.cache(cachetmp);
-				vals = cachetmp.toMap();
-			}
-		}
-		return Response.ok(JsonUtils.toJSON(vals)).build();
-	}
 
-	@DELETE
-	@Path("{type}/{id}/{child}")
-	public Response deleteResourceChild(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @PathParam("id") String id, @PathParam("child") String child) {
-		return deleteResource(context, locale, type, StringUtils.joinResources(id, child));
-	}
+    // fixme: only allowed for corpus?!
+    @GET
+    @Path("/corpus/{id}/{docid}/{rest}/matchInfo")
+    public Response getMatchInfo (@Context SecurityContext ctx,
+            @Context Locale locale, @PathParam("id") String id,
+            @PathParam("docid") String docid, @PathParam("rest") String rest,
+            @QueryParam("foundry") Set<String> foundries,
+            @QueryParam("layer") Set<String> layers,
+            @QueryParam("spans") Boolean spans) {
+        TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
+        spans = spans != null ? spans : false;
+        String matchid = searchKrill.getMatchId(id, docid, rest);
 
-	@DELETE
-	@Path("{type}/{id}")
-	public Response deleteResource(@Context SecurityContext context, @Context Locale locale,
-			@PathParam("type") String type, @PathParam("id") String id) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		type = StringUtils.normalizeHTML(type);
-		id = StringUtils.decodeHTML(id);
-		try {
-			User user = controller.getUser(ctx.getUsername());
-			KustvaktResource r = ResourceFactory.getResource(type);
-			r.setPersistentID(id);
-			// todo: eliminate the need to find the resource first!
-			resourceHandler.deleteResources(user, r);
-		} catch (KustvaktException e) {
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
+        if (layers == null || layers.isEmpty())
+            layers = new HashSet<>();
 
-		return Response.ok().build();
-	}
+        boolean match_only = foundries == null || foundries.isEmpty();
 
-	// fixme: only allowed for corpus?!
-	@GET
-	@Path("/corpus/{id}/{docid}/{rest}/matchInfo")
-	public Response getMatchInfo(@Context SecurityContext ctx, @Context Locale locale, @PathParam("id") String id,
-			@PathParam("docid") String docid, @PathParam("rest") String rest,
-			@QueryParam("foundry") Set<String> foundries, @QueryParam("layer") Set<String> layers,
-			@QueryParam("spans") Boolean spans) {
-		TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
-		spans = spans != null ? spans : false;
-		String matchid = searchKrill.getMatchId(id, docid, rest);
+        User user;
+        try {
+            user = controller.getUser(tokenContext.getUsername());
+        }
+        catch (KustvaktException e) {
 
-		if (layers == null || layers.isEmpty())
-			layers = new HashSet<>();
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
 
-		boolean match_only = foundries == null || foundries.isEmpty();
+        String results;
+        // fixme: checks for policy matching
+        // fixme: currently disabled, due to mishab in foundry/layer spec
+        // fixme:
+        if (foundries != null && foundries.size() > 1000) {
+            Set<String> f_list = new HashSet<>();
+            Set<String> l_list = new HashSet<>();
 
-		User user;
-		try {
-			user = controller.getUser(tokenContext.getUsername());
-		} catch (KustvaktException e) {
+            for (String spl : new ArrayList<>(foundries)) {
+                try {
+                    de.ids_mannheim.korap.security.ac.SecurityManager manager = SecurityManager
+                            .init(spl, user, Permissions.Permission.READ);
+                    if (!manager.isAllowed())
+                        continue;
 
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
+                    String[] sep = StringUtils.splitAnnotations(spl);
+                    if (spl != null) {
+                        f_list.add(sep[0]);
+                        l_list.add(sep[1]);
+                    };
+                    results = searchKrill.getMatch(matchid,
+                            new ArrayList<>(f_list), new ArrayList<>(l_list),
+                            spans, false, true);
+                }
+                catch (EmptyResultException e) {
+                    throw KustvaktResponseHandler.throwit(
+                            StatusCodes.NO_VALUE_FOUND, "Resource not found!",
+                            id);
+                }
+                catch (NotAuthorizedException e) {
+                    throw KustvaktResponseHandler.throwit(
+                            StatusCodes.ACCESS_DENIED, "Permission denied", id);
+                }
 
-		String results;
-		// fixme: checks for policy matching
-		// fixme: currently disabled, due to mishab in foundry/layer spec
-		// fixme:
-		if (foundries != null && foundries.size() > 1000) {
-			Set<String> f_list = new HashSet<>();
-			Set<String> l_list = new HashSet<>();
+            }
+            // all foundries shall be returned
+        }
+        else if (foundries != null && foundries.contains("*")) {
+            Set<Layer> resources;
+            try {
+                resources = ResourceFinder.search(user, Layer.class);
+            }
+            catch (KustvaktException e) {
+                jlog.error("Exception encountered: {}", e.string());
+                throw KustvaktResponseHandler.throwit(e);
+            }
+            // returns foundries and layers.
+            // todo: needs testing!
+            foundries = new HashSet<>();
+            layers = new HashSet<>();
+            for (Layer r : resources) {
+                String[] spl = StringUtils.splitAnnotations(r.getName());
+                if (spl != null) {
+                    foundries.add(spl[0]);
+                    layers.add(spl[1]);
+                }
+            }
+        }
+        try {
+            if (!match_only)
+                results = searchKrill.getMatch(matchid,
+                        new ArrayList<>(foundries), new ArrayList<>(layers),
+                        spans, false, true);
+            else
+                results = searchKrill.getMatch(matchid);
+        }
+        catch (Exception e) {
+            jlog.error("Exception encountered!", e);
+            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+                    e.getMessage(), "");
+        }
+        return Response.ok(results).build();
+    }
 
-			for (String spl : new ArrayList<>(foundries)) {
-				try {
-					de.ids_mannheim.korap.security.ac.SecurityManager manager = SecurityManager.init(spl, user,
-							Permissions.Permission.READ);
-					if (!manager.isAllowed())
-						continue;
 
-					String[] sep = StringUtils.splitAnnotations(spl);
-					if (spl != null) {
-						f_list.add(sep[0]);
-						l_list.add(sep[1]);
-					}
-					;
-					results = searchKrill.getMatch(matchid, new ArrayList<>(f_list), new ArrayList<>(l_list), spans,
-							false, true);
-				} catch (EmptyResultException e) {
-					throw KustvaktResponseHandler.throwit(StatusCodes.NO_VALUE_FOUND, "Resource not found!", id);
-				} catch (NotAuthorizedException e) {
-					throw KustvaktResponseHandler.throwit(StatusCodes.ACCESS_DENIED, "Permission denied", id);
-				}
+    // todo:?!
+    @POST
+    @Path("match/{id}")
+    @Deprecated
+    public Response save (@PathParam("{id}") String id,
+            @QueryParam("d") String description,
+            @Context SecurityContext context) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        // save match for user and later retrieval!
 
-			}
-			// all foundries shall be returned
-		} else if (foundries != null && foundries.contains("*")) {
-			Set<Layer> resources;
-			try {
-				resources = ResourceFinder.search(user, Layer.class);
-			} catch (KustvaktException e) {
-				jlog.error("Exception encountered: {}", e.string());
-				throw KustvaktResponseHandler.throwit(e);
-			}
-			// returns foundries and layers.
-			// todo: needs testing!
-			foundries = new HashSet<>();
-			layers = new HashSet<>();
-			for (Layer r : resources) {
-				String[] spl = StringUtils.splitAnnotations(r.getName());
-				if (spl != null) {
-					foundries.add(spl[0]);
-					layers.add(spl[1]);
-				}
-			}
-		}
-		try {
-			if (!match_only)
-				results = searchKrill.getMatch(matchid, new ArrayList<>(foundries), new ArrayList<>(layers), spans,
-						false, true);
-			else
-				results = searchKrill.getMatch(matchid);
-		} catch (Exception e) {
-			jlog.error("Exception encountered!", e);
-			throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT, e.getMessage(), "");
-		}
-		return Response.ok(results).build();
-	}
+        // KustvaktResource match = new QueryMatch(id);
+        // match.setDescription(description);
+        // match.setCreated(TimeUtils.getNow().getMillis());
+        // try {
+        // this.resourceHandler.storeResources(controller.getUser(ctx), match);
+        // } catch (KustvaktException | NotAuthorizedException e) {
+        // throw MappedHTTPResponse.throwit(e);
+        // }
 
-	// todo:?!
-	@POST
-	@Path("match/{id}")
-	@Deprecated
-	public Response save(@PathParam("{id}") String id, @QueryParam("d") String description,
-			@Context SecurityContext context) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		// save match for user and later retrieval!
+        return Response.ok().build();
+    }
 
-		// KustvaktResource match = new QueryMatch(id);
-		// match.setDescription(description);
-		// match.setCreated(TimeUtils.getNow().getMillis());
-		// try {
-		// this.resourceHandler.storeResources(controller.getUser(ctx), match);
-		// } catch (KustvaktException | NotAuthorizedException e) {
-		// throw MappedHTTPResponse.throwit(e);
-		// }
 
-		return Response.ok().build();
-	}
+    @GET
+    @Path("matches")
+    @Deprecated
+    public Response get (@Context SecurityContext context) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        // todo save match for user and later retrieval!
+        // todo: retrieve matches in range! --choices: date, document, id
+        // (matchid)
+        return Response.ok().build();
+    }
 
-	@GET
-	@Path("matches")
-	@Deprecated
-	public Response get(@Context SecurityContext context) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		// todo save match for user and later retrieval!
-		// todo: retrieve matches in range! --choices: date, document, id
-		// (matchid)
-		return Response.ok().build();
-	}
 
-	@DELETE
-	@Path("match/{id}")
-	@Deprecated
-	public Response remove(@PathParam("{id}") String id, @Context SecurityContext context) {
-		TokenContext ctx = (TokenContext) context.getUserPrincipal();
-		// save match for user and later retrieval!
-		try {
-			this.resourceHandler.deleteResources(this.controller.getUser(ctx.getUsername()), id);
-		} catch (KustvaktException e) {
-			jlog.error("Exception encountered: {}", e.string());
-			throw KustvaktResponseHandler.throwit(e);
-		}
+    @DELETE
+    @Path("match/{id}")
+    @Deprecated
+    public Response remove (@PathParam("{id}") String id,
+            @Context SecurityContext context) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        // save match for user and later retrieval!
+        try {
+            this.resourceHandler.deleteResources(
+                    this.controller.getUser(ctx.getUsername()), id);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: {}", e.string());
+            throw KustvaktResponseHandler.throwit(e);
+        }
 
-		return Response.ok().build();
-	}
+        return Response.ok().build();
+    }
 
 }
diff --git a/src/main/resources/db/sqlite/V1__Initial_version.sql b/src/main/resources/db/sqlite/V1__Initial_version.sql
index 55641ae..943d3cd 100644
--- a/src/main/resources/db/sqlite/V1__Initial_version.sql
+++ b/src/main/resources/db/sqlite/V1__Initial_version.sql
@@ -13,7 +13,7 @@
 
 CREATE TABLE IF NOT EXISTS admin_users (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
-user_id INTEGER NOT NULL UNIQUE,
+user_id INTEGER NOT NULL,
 foreign key (user_id)
 references korap_users (id)
 );
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
index aa99ac9..0226217 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
@@ -55,105 +55,184 @@
 import de.ids_mannheim.korap.utils.JsonUtils;
 
 /**
- * This class tests services of a running Kustvakt server with a MySQL database.
- * Please check the database configuration in src/main/resources/jdbc.properties
+ * This class tests services of a running Kustvakt server with a MySQL
+ * database.
+ * Please check the database configuration in
+ * src/main/resources/jdbc.properties
  * and run the server before running the tests.
  * 
- * See {@link ResourceServiceTest} for tests using an in-memory database.
+ * See {@link ResourceServiceTest} for tests using an in-memory
+ * database.
  * 
  * @author margaretha
  *
  */
 public class KustvaktServerTest extends BeanConfigTest {
-	@Test
-	public void testCreatePolicy() throws IOException, URISyntaxException {
-		
-		HttpClient httpClient = HttpClients.createDefault();;
-		
-        String id = UUID.randomUUID().toString();
-		URIBuilder builder = new URIBuilder();
-		builder.setScheme("http")
-			.setHost("localhost")
-			.setPort(8089).setPath("/api/v0.1/admin/createPolicies/" + id)
-			.setParameter("type", "virtualcollection")
-			.setParameter("name", "Goethe VC")
-			.setParameter("description", "Goethe corpus")
-			.setParameter("group", "public")
-			.setParameter("perm", Permission.READ.name())
-			.setParameter("loc", "")
-			.setParameter("expire", "");
+    @Test
+    public void testCreatePolicy () throws IOException, URISyntaxException {
 
-		URI uri = builder.build();
-		HttpPost httppost = new HttpPost(uri);
-		
-		httppost.addHeader(Attributes.AUTHORIZATION, BasicHttpAuth.encode("kustvakt", "kustvakt2015"));
-		HttpResponse response = httpClient.execute(httppost);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(),
+        HttpClient httpClient = HttpClients.createDefault();;
+
+        String id = UUID.randomUUID().toString();
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/admin/createPolicies/" + id)
+                .setParameter("type", "virtualcollection")
+                .setParameter("name", "Goethe VC")
+                .setParameter("description", "Goethe corpus")
+                .setParameter("group", "public")
+                .setParameter("perm", Permission.READ.name())
+                .setParameter("loc", "")
+                .setParameter("expire", "");
+
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
+
+        httppost.addHeader(Attributes.AUTHORIZATION,
+                BasicHttpAuth.encode("kustvakt", "kustvakt2015"));
+        HttpResponse response = httpClient.execute(httppost);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatusLine().getStatusCode());
 
-	}
+    }
 
-	@Test
-	public void testWrongAuthorization() throws IOException, URISyntaxException {
-		HttpResponse response = testResourceStore("wezrowerowj");
-		assertEquals(ClientResponse.Status.UNAUTHORIZED.getStatusCode(), response.getStatusLine().getStatusCode());
-	}
 
-	@Test
-	public void testCorrectAuthorization() throws IOException, URISyntaxException, KustvaktException {
+    @Test
+    public void testCreatePolicyForFoundry ()
+            throws IOException, URISyntaxException {
 
-		HttpResponse response = testResourceStore("kustvakt2015");
-		HttpEntity entity = response.getEntity();
-		String content = null;
+        HttpClient httpClient = HttpClients.createDefault();;
 
-		if (entity != null) {
-			InputStream is = entity.getContent();
-			try {
-				content = IOUtils.toString(is, "UTF-8");
-			} finally {
-				is.close();
-			}
-		}
+        String id = UUID.randomUUID().toString();
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/admin/createPolicies/" + id)
+                .setParameter("type", "foundry")
+                .setParameter("name", "stanford")
+                .setParameter("description", "stanford parser")
+                .setParameter("group", "public")
+                .setParameter("perm", Permission.READ.name())
+                .setParameter("loc", "255.255.255.0")
+                .setParameter("expire", "30D");
 
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatusLine().getStatusCode());
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
 
-		JsonNode node = JsonUtils.readTree(content);
-		assertNotNull(node);
-		assertTrue(node.isObject());
-		assertEquals("Goethe", node.path("name").asText());
-		assertEquals("Goethe corpus", node.path("description").asText());
+        httppost.addHeader(Attributes.AUTHORIZATION,
+                BasicHttpAuth.encode("kustvakt", "kustvakt2015"));
+        HttpResponse response = httpClient.execute(httppost);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatusLine().getStatusCode());
 
-		// checkResourceInDB(node.path("id").asText());
-	}
+    }
 
-	public HttpResponse testResourceStore(String password) throws IOException, URISyntaxException {
 
-		HttpClient httpclient = HttpClients.createDefault();
-		URIBuilder builder = new URIBuilder();
-		builder.setScheme("http").setHost("localhost").setPort(8089).setPath("/api/v0.1/virtualcollection")
-				.setParameter("filter", "httpclient").setParameter("name", "Goethe")
-				.setParameter("description", "Goethe corpus");
-		URI uri = builder.build();
-		HttpPost httppost = new HttpPost(uri);
-		httppost.addHeader(Attributes.AUTHORIZATION, BasicHttpAuth.encode("kustvakt", password));
-		return httpclient.execute(httppost);
+    @Test
+    public void testCreatePolicyWithMultiplePermissions ()
+            throws IOException, URISyntaxException {
 
-	}
+        HttpClient httpClient = HttpClients.createDefault();;
 
-	private void checkResourceInDB(String id) throws KustvaktException {
+        String id = UUID.randomUUID().toString();
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/admin/createPolicies/" + id)
+                .setParameter("type", "corpus").setParameter("name", "Brown")
+                .setParameter("description", "Brown corpus")
+                .setParameter("group", "public")
+                .setParameter("perm", Permission.READ.name())
+                .setParameter("perm", Permission.WRITE.name())
+                .setParameter("perm", Permission.DELETE.name())
+                .setParameter("loc", "255.255.255.0")
+                .setParameter("expire", "30D");
 
-		ResourceDao<?> dao = new ResourceDao<>(helper().getContext().getPersistenceClient());
-		assertEquals("sqlite", helper().getContext().getPersistenceClient().getDatabase());
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
 
-		assertNotEquals(0, dao.size());
-		KustvaktResource res = dao.findbyId(id, User.UserFactory.getDemoUser());
-		assertNotNull(res);
-		Assert.assertEquals(true, res.getField("testVar").toString().startsWith("testVal_"));
-	}
+        httppost.addHeader(Attributes.AUTHORIZATION,
+                BasicHttpAuth.encode("kustvakt", "kustvakt2015"));
+        HttpResponse response = httpClient.execute(httppost);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatusLine().getStatusCode());
 
-	@Override
-	public void initMethod() throws KustvaktException {
-		// TODO Auto-generated method stub
+    }
 
-	}
+
+    @Test
+    public void testWrongAuthorization ()
+            throws IOException, URISyntaxException {
+        HttpResponse response = testResourceStore("wezrowerowj");
+        assertEquals(ClientResponse.Status.UNAUTHORIZED.getStatusCode(),
+                response.getStatusLine().getStatusCode());
+    }
+
+
+    @Test
+    public void testCorrectAuthorization ()
+            throws IOException, URISyntaxException, KustvaktException {
+
+        HttpResponse response = testResourceStore("kustvakt2015");
+        HttpEntity entity = response.getEntity();
+        String content = null;
+
+        if (entity != null) {
+            InputStream is = entity.getContent();
+            try {
+                content = IOUtils.toString(is, "UTF-8");
+            }
+            finally {
+                is.close();
+            }
+        }
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatusLine().getStatusCode());
+
+        JsonNode node = JsonUtils.readTree(content);
+        assertNotNull(node);
+        assertTrue(node.isObject());
+        assertEquals("Goethe", node.path("name").asText());
+        assertEquals("Goethe corpus", node.path("description").asText());
+    }
+
+
+    public HttpResponse testResourceStore (String password)
+            throws IOException, URISyntaxException {
+
+        HttpClient httpclient = HttpClients.createDefault();
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/virtualcollection")
+                .setParameter("filter", "httpclient")
+                .setParameter("name", "Goethe")
+                .setParameter("description", "Goethe corpus");
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
+        httppost.addHeader(Attributes.AUTHORIZATION,
+                BasicHttpAuth.encode("kustvakt", password));
+        return httpclient.execute(httppost);
+
+    }
+
+
+    private void checkResourceInDB (String id) throws KustvaktException {
+
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+        assertEquals("sqlite",
+                helper().getContext().getPersistenceClient().getDatabase());
+
+        assertNotEquals(0, dao.size());
+        KustvaktResource res = dao.findbyId(id, User.UserFactory.getDemoUser());
+        assertNotNull(res);
+        Assert.assertEquals(true,
+                res.getField("testVar").toString().startsWith("testVal_"));
+    }
+
+
+    @Override
+    public void initMethod () throws KustvaktException {
+        // TODO Auto-generated method stub
+
+    }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/PolicyServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/PolicyServiceTest.java
index 6959924..c48f40c 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/PolicyServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/PolicyServiceTest.java
@@ -15,6 +15,8 @@
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.interfaces.db.PolicyHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.ResourceOperationIface;
+import de.ids_mannheim.korap.resources.Corpus;
+import de.ids_mannheim.korap.resources.Foundry;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.resources.Permissions;
 import de.ids_mannheim.korap.resources.Permissions.Permission;
@@ -31,34 +33,36 @@
  */
 public class PolicyServiceTest extends FastJerseyTest {
 
-	@BeforeClass
-	public static void configure() throws Exception {
-		FastJerseyTest.setPackages("de.ids_mannheim.korap.web.service.full", "de.ids_mannheim.korap.web.filter",
-				"de.ids_mannheim.korap.web.utils");
-	}
+    private User user = UserFactory.getDemoUser();
 
-	@Test
-    public void testCreatePolicyForResource() throws IOException, KustvaktException {
-		String id = UUID.randomUUID().toString();
-    	ClientResponse response = resource()
-                .path(getAPIVersion())
-                .path("admin")
-                .path("createPolicies")
-                .path(id)
+
+    @BeforeClass
+    public static void configure () throws Exception {
+        FastJerseyTest.setPackages("de.ids_mannheim.korap.web.service.full",
+                "de.ids_mannheim.korap.web.filter",
+                "de.ids_mannheim.korap.web.utils");
+    }
+
+
+    @Test
+    public void testCreatePolicyForVirtualCollection ()
+            throws IOException, KustvaktException {
+        String id = UUID.randomUUID().toString();
+        ClientResponse response = resource().path(getAPIVersion()).path("admin")
+                .path("createPolicies").path(id)
                 .queryParam("type", "virtualcollection")
                 .queryParam("name", "Goethe VC")
                 .queryParam("description", "Goethe corpus")
                 .queryParam("group", "public")
                 .queryParam("perm", Permission.READ.name())
-                .queryParam("loc", "")
                 .queryParam("expire", "")
                 .header(Attributes.AUTHORIZATION,
-                        BasicHttpAuth.encode("kustvakt","kustvakt2015"))
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
                 .post(ClientResponse.class);
-        
+
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
-        
+
         // Check the policies
         PolicyHandlerIface dao = helper().getContext().getPolicyDbProvider();
         List<SecurityPolicy> policies = dao.getPolicies(
@@ -66,18 +70,108 @@
                 Permissions.Permission.READ.toByte());
         assertEquals(2, policies.size());
         
-        // Check resource store
-        List<ResourceOperationIface> providers= (List<ResourceOperationIface>) helper().getContext().getResourceProviders();
-        ResourceOperationIface resourceDao = providers.get(0);
-        
-        User user = UserFactory.getDemoUser();
-		KustvaktResource resource = resourceDao.findbyId(id,user);
-		assertEquals("Goethe VC", resource.getName());
-        	
-	}
+        policies = dao.getPoliciesByPersistentId(
+                new PolicyCondition("public"), VirtualCollection.class,
+                Permissions.Permission.READ.toByte(),id);
+        assertEquals(1, policies.size());
+        assertEquals(id, policies.get(0).getTarget());
 
-	@Override
-	public void initMethod() throws KustvaktException {
-		helper().runBootInterfaces();
-	}
+        // Check the resource
+        List<ResourceOperationIface> providers = (List<ResourceOperationIface>) helper()
+                .getContext().getResourceProviders();
+        ResourceOperationIface resourceDao = providers.get(0);
+
+        User user = UserFactory.getDemoUser();
+        KustvaktResource resource = resourceDao.findbyId(id, user);
+        assertEquals("Goethe VC", resource.getName());
+
+    }
+
+
+    @Test
+    public void testCreatePolicyForFoundry ()
+            throws IOException, KustvaktException {
+        String id = UUID.randomUUID().toString();
+        ClientResponse response = resource().path(getAPIVersion()).path("admin")
+                .path("createPolicies").path(id).queryParam("type", "foundry")
+                .queryParam("name", "stanford")
+                .queryParam("description", "stanford parser")
+                .queryParam("group", "public")
+                .queryParam("perm", Permission.READ.name())
+                .queryParam("loc", "255.255.255.0")
+                .queryParam("expire", "30D")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        // Check the resource store
+        List<ResourceOperationIface> providers = (List<ResourceOperationIface>) helper()
+                .getContext().getResourceProviders();
+        ResourceOperationIface resourceDao = providers.get(0);
+        KustvaktResource resource = resourceDao.findbyId(id, user);
+        assertEquals("stanford", resource.getName());
+
+        // Check the policies
+        PolicyHandlerIface dao = helper().getContext().getPolicyDbProvider();
+        List<SecurityPolicy> policies = dao.getPoliciesByPersistentId(
+                new PolicyCondition("public"), Foundry.class,
+                Permissions.Permission.READ.toByte(),id);
+        assertEquals(1, policies.size());
+        assertEquals("255.255.255.0",policies.get(0).getContext().getIpmask());
+
+    }
+
+
+    @Test
+    public void testCreatePolicyForMultiplePermissions ()
+            throws IOException, KustvaktException {
+        String id = UUID.randomUUID().toString();
+        ClientResponse response = resource().path(getAPIVersion()).path("admin")
+                .path("createPolicies").path(id).queryParam("type", "corpus")
+                .queryParam("name", "Brown")
+                .queryParam("description", "Brown corpus")
+                .queryParam("group", "public")
+                .queryParam("perm", Permission.READ.name())
+                .queryParam("perm", Permission.WRITE.name())
+                .queryParam("perm", Permission.DELETE.name())
+                .queryParam("expire", "30D")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        // Check resource store
+        List<ResourceOperationIface> providers = (List<ResourceOperationIface>) helper()
+                .getContext().getResourceProviders();
+        ResourceOperationIface resourceDao = providers.get(0);
+
+        KustvaktResource resource = resourceDao.findbyId(id, user);
+        assertEquals("Brown", resource.getName());
+
+        // Check the policies
+        PolicyHandlerIface dao = helper().getContext().getPolicyDbProvider();
+        List<SecurityPolicy> policies = dao.getPoliciesByPersistentId(
+                new PolicyCondition("public"), Corpus.class,
+                Permissions.Permission.WRITE.toByte(),id);
+        assertEquals(1, policies.size());
+        assertEquals(id, policies.get(0).getTarget());
+        
+        policies = dao.getPoliciesByPersistentId(
+                new PolicyCondition("public"), Corpus.class,
+                Permissions.Permission.DELETE.toByte(),id);
+        assertEquals(1, policies.size());
+        assertEquals(id, policies.get(0).getTarget());
+    }
+
+
+    @Override
+    public void initMethod () throws KustvaktException {
+        helper().runBootInterfaces();
+    }
 }
+
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
index d036b57..fed448d 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
@@ -18,6 +18,7 @@
 
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.handlers.ResourceDao;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
 import de.ids_mannheim.korap.resources.KustvaktResource;
@@ -301,7 +302,35 @@
                 User.UserFactory.getDemoUser());
         assertNotNull(res);
         Assert.assertEquals("Goethe",res.getName().toString());
-    
+        
+        // no update resource service
+        response = resource()
+                .path(getAPIVersion())
+                .path("virtualcollection")
+                .path(id)
+                .queryParam("name", "Goethe")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+        
+        assertEquals(StatusCodes.NOTHING_CHANGED, response.getStatus());
+        
+        // update resource service
+        response = resource()
+                .path(getAPIVersion())
+                .path("virtualcollection")
+                .path(id)
+                .queryParam("name", "Goethe collection")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+        
+        res = dao.findbyId(id,
+                User.UserFactory.getDemoUser());
+        assertNotNull(res);
+        Assert.assertEquals("Goethe collection",res.getName().toString());
+        
+        
         // delete resource service
     	response = resource()
                 .path(getAPIVersion())
@@ -340,36 +369,6 @@
         assertEquals("WPD15", node.path("id").asText());
     }
 
-    
-
-//    @Test
-//    public void testCreatePolicyForResource() {
-//    	ClientResponse response = resource()
-//                .path(getAPIVersion())
-//                .path("admin")
-//                .path("createPolicies")
-//                .path(UUID.randomUUID().toString())
-//                .queryParam("type", "virtualcollection")
-//                .queryParam("name", "Goethe")
-//                .queryParam("description", "Goethe corpus")
-//                .queryParam("group", "public")
-//                .queryParam("perm", Permission.READ.name())
-//                .queryParam("loc", "")
-//                .queryParam("expire", "")
-//                .header(Attributes.AUTHORIZATION,
-//                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
-//                .post(ClientResponse.class);
-//        
-//        assertEquals(ClientResponse.Status.OK.getStatusCode(),
-//                response.getStatus());
-//        
-//        String ent = response.getEntity(String.class);
-//        JsonNode node = JsonUtils.readTree(ent);
-//        assertNotNull(node);
-//        assertTrue(node.isObject());
-//        assertEquals("GOE", node.path("id").asText());
-//	}
-    
     @Test
     public void testCorpusGet2 () {
     	ClientResponse response = resource().path(getAPIVersion())
