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();
+    }
 
 }
