Added listing available queries for users.

Change-Id: I8895226a3fe095f1d997e81fddf7428bb1e9c904
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java b/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java
index 57d1d9b..06f6ee5 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java
+++ b/full/src/main/java/de/ids_mannheim/korap/config/NamedVCLoader.java
@@ -90,7 +90,7 @@
                 cacheVC(json, filename);
                 try {
                     VirtualCorpus vc = vcService.searchVCByName("system",
-                            filename, "system");
+                            filename, "system", QueryType.VIRTUAL_CORPUS);
                     if (vc != null) {
                         if (DEBUG) {
                             jlog.debug("Delete existing vc: " + filename);
diff --git a/full/src/main/java/de/ids_mannheim/korap/constant/QueryType.java b/full/src/main/java/de/ids_mannheim/korap/constant/QueryType.java
index d223056..cd47332 100644
--- a/full/src/main/java/de/ids_mannheim/korap/constant/QueryType.java
+++ b/full/src/main/java/de/ids_mannheim/korap/constant/QueryType.java
@@ -1,7 +1,13 @@
 package de.ids_mannheim.korap.constant;
 
+import org.apache.commons.lang.StringUtils;
+
 public enum QueryType {
 
     QUERY,
     VIRTUAL_CORPUS;
+    
+    public String displayName () {
+        return StringUtils.capitalize(name().toLowerCase().replace("_", " "));
+    }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
index bbd9f2c..fb1dc84 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
@@ -22,9 +22,9 @@
 
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
 import de.ids_mannheim.korap.constant.QueryType;
+import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.constant.UserGroupStatus;
 import de.ids_mannheim.korap.constant.VirtualCorpusAccessStatus;
-import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.entity.UserGroup;
 import de.ids_mannheim.korap.entity.UserGroupMember;
 import de.ids_mannheim.korap.entity.UserGroupMember_;
@@ -75,9 +75,9 @@
     }
 
     public void editVirtualCorpus (VirtualCorpus vc, String name,
-            ResourceType type, CorpusAccess requiredAccess,
-            String koralQuery, String definition, String description,
-            String status, boolean isCached) throws KustvaktException {
+            ResourceType type, CorpusAccess requiredAccess, String koralQuery,
+            String definition, String description, String status,
+            boolean isCached) throws KustvaktException {
 
         if (name != null && !name.isEmpty()) {
             vc.setName(name);
@@ -131,31 +131,30 @@
      */
     @SuppressWarnings("unchecked")
     public List<VirtualCorpus> retrieveVCByType (ResourceType type,
-            String createdBy) throws KustvaktException {
+            String createdBy, QueryType queryType) throws KustvaktException {
 
         CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
         CriteriaQuery<VirtualCorpus> query =
                 criteriaBuilder.createQuery(VirtualCorpus.class);
         Root<VirtualCorpus> virtualCorpus = query.from(VirtualCorpus.class);
 
-        Predicate conditions = null;
+        Predicate conditions = criteriaBuilder
+                .equal(virtualCorpus.get(VirtualCorpus_.queryType), queryType);
         if (createdBy != null && !createdBy.isEmpty()) {
-            conditions = criteriaBuilder.equal(
-                    virtualCorpus.get(VirtualCorpus_.createdBy), createdBy);
+            conditions = criteriaBuilder.and(conditions, criteriaBuilder.equal(
+                    virtualCorpus.get(VirtualCorpus_.createdBy), createdBy));
             if (type != null) {
                 conditions = criteriaBuilder.and(conditions, criteriaBuilder
                         .equal(virtualCorpus.get(VirtualCorpus_.type), type));
             }
         }
         else if (type != null) {
-            conditions = criteriaBuilder
-                    .equal(virtualCorpus.get(VirtualCorpus_.type), type);
+            conditions = criteriaBuilder.and(conditions, criteriaBuilder
+                    .equal(virtualCorpus.get(VirtualCorpus_.type), type));
         }
 
         query.select(virtualCorpus);
-        if (conditions != null) {
-            query.where(conditions);
-        }
+        query.where(conditions);
         Query q = entityManager.createQuery(query);
         return q.getResultList();
     }
@@ -178,7 +177,7 @@
         }
         catch (NoResultException e) {
             throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
-                    "Virtual corpus with id: "+ id+" is not found",
+                    "Virtual corpus with id: " + id + " is not found",
                     String.valueOf(id), e);
         }
         return vc;
@@ -229,8 +228,8 @@
     }
 
     @SuppressWarnings("unchecked")
-    public List<VirtualCorpus> retrieveOwnerVC (String userId)
-            throws KustvaktException {
+    public List<VirtualCorpus> retrieveOwnerVC (String userId,
+            QueryType queryType) throws KustvaktException {
         ParameterChecker.checkStringValue(userId, "userId");
 
         CriteriaBuilder builder = entityManager.getCriteriaBuilder();
@@ -238,9 +237,14 @@
                 builder.createQuery(VirtualCorpus.class);
 
         Root<VirtualCorpus> virtualCorpus = query.from(VirtualCorpus.class);
+        Predicate conditions = builder.and(
+                builder.equal(virtualCorpus.get(VirtualCorpus_.createdBy),
+                        userId),
+                builder.equal(virtualCorpus.get(VirtualCorpus_.queryType),
+                        queryType));
+
         query.select(virtualCorpus);
-        query.where(builder.equal(virtualCorpus.get(VirtualCorpus_.createdBy),
-                userId));
+        query.where(conditions);
 
         Query q = entityManager.createQuery(query);
         return q.getResultList();
@@ -269,7 +273,7 @@
     }
 
     @SuppressWarnings("unchecked")
-    public List<VirtualCorpus> retrieveGroupVCByUser (String userId)
+    public List<VirtualCorpus> retrieveGroupVCByUser (String userId, QueryType queryType)
             throws KustvaktException {
         ParameterChecker.checkStringValue(userId, "userId");
 
@@ -287,6 +291,9 @@
         // builder.notEqual(access.get(VirtualCorpusAccess_.status),
         // VirtualCorpusAccessStatus.DELETED));
 
+        Predicate type = builder
+                .equal(virtualCorpus.get(VirtualCorpus_.queryType), queryType);
+                
         Predicate corpusStatus =
                 builder.notEqual(access.get(VirtualCorpusAccess_.status),
                         VirtualCorpusAccessStatus.DELETED);
@@ -305,26 +312,29 @@
 
         query.select(virtualCorpus);
         query.where(
-                builder.and(corpusStatus, userGroupStatus, memberStatus, user));
+                builder.and(type, corpusStatus, userGroupStatus, memberStatus, user));
 
         Query q = entityManager.createQuery(query);
         return q.getResultList();
     }
 
-    public List<VirtualCorpus> retrieveVCByUser (String userId)
-            throws KustvaktException {
+    public List<VirtualCorpus> retrieveVCByUser (String userId,
+            QueryType queryType) throws KustvaktException {
         ParameterChecker.checkStringValue(userId, "userId");
+        ParameterChecker.checkObjectValue(queryType, "queryType");
 
         CriteriaBuilder builder = entityManager.getCriteriaBuilder();
         CriteriaQuery<VirtualCorpus> query =
                 builder.createQuery(VirtualCorpus.class);
 
         Root<VirtualCorpus> virtualCorpus = query.from(VirtualCorpus.class);
-        Predicate predicate = builder.or(
-                builder.equal(virtualCorpus.get(VirtualCorpus_.createdBy),
-                        userId),
-                builder.equal(virtualCorpus.get(VirtualCorpus_.type),
-                        ResourceType.SYSTEM));
+        Predicate predicate = builder.and(
+                builder.equal(virtualCorpus.get(VirtualCorpus_.queryType),
+                        queryType),
+                builder.or(builder.equal(
+                        virtualCorpus.get(VirtualCorpus_.createdBy), userId),
+                        builder.equal(virtualCorpus.get(VirtualCorpus_.type),
+                                ResourceType.SYSTEM)));
 
         query.select(virtualCorpus);
         query.where(predicate);
@@ -333,7 +343,7 @@
 
         @SuppressWarnings("unchecked")
         List<VirtualCorpus> vcList = q.getResultList();
-        List<VirtualCorpus> groupVC = retrieveGroupVCByUser(userId);
+        List<VirtualCorpus> groupVC = retrieveGroupVCByUser(userId, queryType);
         Set<VirtualCorpus> vcSet = new HashSet<VirtualCorpus>();
         vcSet.addAll(vcList);
         vcSet.addAll(groupVC);
diff --git a/full/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java b/full/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
index c4193ed..4b7e755 100644
--- a/full/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
+++ b/full/src/main/java/de/ids_mannheim/korap/rewrite/QueryReferenceRewrite.java
@@ -7,11 +7,13 @@
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.constant.QueryType;
+import de.ids_mannheim.korap.entity.VirtualCorpus;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.rewrite.KoralNode.RewriteIdentifier;
-import de.ids_mannheim.korap.service.QueryReferenceService;
+import de.ids_mannheim.korap.service.VirtualCorpusService;
 import de.ids_mannheim.korap.user.User;
-import de.ids_mannheim.korap.util.StatusCodes;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
 /**
@@ -27,10 +29,7 @@
 public class QueryReferenceRewrite implements RewriteTask.RewriteQuery {
 
     @Autowired
-    private KustvaktConfiguration config;
-
-    @Autowired
-    private QueryReferenceService qService;
+    private VirtualCorpusService service;
 
     @Override
     public KoralNode rewriteQuery (KoralNode node,
@@ -49,28 +48,34 @@
             && koralNode.get("@type").equals("koral:queryRef")) {
             if (!koralNode.has("ref")) {
                 throw new KustvaktException(
-                    StatusCodes.MISSING_QUERY_REFERENCE,
+                    de.ids_mannheim.korap.util.StatusCodes.MISSING_QUERY_REFERENCE,
                     "ref is not found"
                     );
             }
             else {
                 String queryRefName = koralNode.get("ref");
                 String queryRefOwner = "system";
-                boolean ownerExist = false;
                 if (queryRefName.contains("/")) {
                     String[] names = queryRefName.split("/");
                     if (names.length == 2) {
                         queryRefOwner = names[0];
                         queryRefName = names[1];
-                        ownerExist = true;
                     }
                 }
 
-                JsonNode qref = qService.searchQueryByName(
-                    username,
-                    queryRefName,
-                    queryRefOwner);
+                VirtualCorpus qr = service.searchVCByName(username,
+                        queryRefName, queryRefOwner, QueryType.QUERY);
 
+                if (qr == null) {
+                    throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
+                            "Query reference " + queryRefName
+                                    + " is not found.",
+                            String.valueOf(queryRefName));
+                }
+
+                // TODO:
+                //   checkVCAcess(q, username);
+                JsonNode qref = JsonUtils.readTree(qr.getKoralQuery());;
                 rewriteQuery(qref,koralNode);
             }
         }
@@ -87,17 +92,6 @@
     }
 
 
-    private void removeOwner (String koralQuery,
-                              String queryRefOwner,
-                              KoralNode koralNode) throws KustvaktException {
-        JsonNode jsonNode = koralNode.rawNode();
-        String ref = jsonNode.at("/ref").asText();
-        koralNode.remove("ref", new RewriteIdentifier("ref", ref));
-
-        ref = ref.substring(queryRefOwner.length() + 1, ref.length());
-        koralNode.set("ref", ref, new RewriteIdentifier("ref", ref));
-    }
-
     private void rewriteQuery (JsonNode qref, KoralNode koralNode)
         throws KustvaktException {
         JsonNode jsonNode = koralNode.rawNode();
diff --git a/full/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java b/full/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java
index 3f25da1..297680e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java
+++ b/full/src/main/java/de/ids_mannheim/korap/rewrite/VirtualCorpusRewrite.java
@@ -7,6 +7,7 @@
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.constant.QueryType;
 import de.ids_mannheim.korap.entity.VirtualCorpus;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.rewrite.KoralNode.RewriteIdentifier;
@@ -71,10 +72,11 @@
                 }
                 
                 VirtualCorpus vc =
-                        vcService.searchVCByName(username, vcName, vcOwner);
+                        vcService.searchVCByName(username, vcName, vcOwner, QueryType.VIRTUAL_CORPUS);
                 if (!vc.isCached()) {
                     rewriteVC(vc, koralNode);
                 }
+                // required for named-vc since they are stored by filenames in the cache
                 else if (ownerExist) {
                     removeOwner(vc.getKoralQuery(), vcOwner, koralNode);
                 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
index 9d5ea85..0dc9f84 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
@@ -91,15 +91,15 @@
         }
     }
 
-    public List<VirtualCorpusDto> listOwnerVC (String username, String vcCreator)
-            throws KustvaktException {
+    public List<VirtualCorpusDto> listOwnerVC (String username,
+            String vcCreator, QueryType queryType) throws KustvaktException {
         verifyUsername(username, vcCreator);
-        List<VirtualCorpus> vcList = vcDao.retrieveOwnerVC(username);
-        return createVCDtos(vcList);
+        List<VirtualCorpus> vcList = vcDao.retrieveOwnerVC(username, queryType);
+        return createVCDtos(vcList, queryType);
     }
 
     public List<VirtualCorpusDto> listAvailableVCForUser (
-            String authenticatedUsername, String username)
+            String authenticatedUsername, String username, QueryType queryType)
             throws KustvaktException {
 
         boolean isAdmin = adminDao.isAdmin(authenticatedUsername);
@@ -115,20 +115,22 @@
         else {
             username = authenticatedUsername;
         }
-        List<VirtualCorpus> vcList = vcDao.retrieveVCByUser(username);
-        return createVCDtos(vcList);
+        List<VirtualCorpus> vcList =
+                vcDao.retrieveVCByUser(username, queryType);
+        return createVCDtos(vcList, queryType);
     }
 
     public List<VirtualCorpusDto> listVCByType (String username,
-            String createdBy, ResourceType type) throws KustvaktException {
+            String createdBy, ResourceType type, QueryType queryType)
+            throws KustvaktException {
 
         boolean isAdmin = adminDao.isAdmin(username);
 
         if (isAdmin) {
             List<VirtualCorpus> virtualCorpora =
-                    vcDao.retrieveVCByType(type, createdBy);
+                    vcDao.retrieveVCByType(type, createdBy, queryType);
             Collections.sort(virtualCorpora);
-            return createVCDtos(virtualCorpora);
+            return createVCDtos(virtualCorpora, queryType);
         }
         else {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
@@ -137,14 +139,18 @@
     }
 
     private ArrayList<VirtualCorpusDto> createVCDtos (
-            List<VirtualCorpus> vcList) throws KustvaktException {
+            List<VirtualCorpus> vcList, QueryType queryType)
+            throws KustvaktException {
         ArrayList<VirtualCorpusDto> dtos = new ArrayList<>(vcList.size());
         VirtualCorpus vc;
         Iterator<VirtualCorpus> i = vcList.iterator();
         while (i.hasNext()) {
             vc = i.next();
             String json = vc.getKoralQuery();
-            String statistics = krill.getStatistics(json);
+            String statistics = null;
+            if (queryType.equals(QueryType.VIRTUAL_CORPUS)) {
+                statistics = krill.getStatistics(json);
+            }
             VirtualCorpusDto vcDto =
                     converter.createVirtualCorpusDto(vc, statistics);
             dtos.add(vcDto);
@@ -204,7 +210,7 @@
         if (vc == null) {
             String vcCode = createdBy + "/" + vcName;
             throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
-                    "Virtual corpus "+ vcCode+" is not found.",
+                    "Virtual corpus " + vcCode + " is not found.",
                     String.valueOf(vcCode));
         }
         else if (vc.getCreatedBy().equals(username)
@@ -217,7 +223,7 @@
                 userGroupService.deleteAutoHiddenGroup(
                         access.getUserGroup().getId(), "system");
             }
-            if (KrillCollection.cache.get(vc.getName())!=null){
+            if (KrillCollection.cache.get(vc.getName()) != null) {
                 KrillCollection.cache.remove(vc.getName());
             }
             vcDao.deleteVirtualCorpus(vc);
@@ -228,17 +234,17 @@
         }
     }
 
-//    @Deprecated
-//    public void editVC (VirtualCorpusJson vcJson, String username)
-//            throws KustvaktException {
-//        ParameterChecker.checkIntegerValue(vcJson.getId(), "id");
-//        VirtualCorpus vc = vcDao.retrieveVCById(vcJson.getId());
-//        editVC(vc, vcJson, vcJson.getName(), username);
-//    }
+    // @Deprecated
+    // public void editVC (VirtualCorpusJson vcJson, String username)
+    // throws KustvaktException {
+    // ParameterChecker.checkIntegerValue(vcJson.getId(), "id");
+    // VirtualCorpus vc = vcDao.retrieveVCById(vcJson.getId());
+    // editVC(vc, vcJson, vcJson.getName(), username);
+    // }
 
     public Status handlePutRequest (String username, String vcCreator,
             String vcName, QueryJson vcJson) throws KustvaktException {
-        
+
         verifyUsername(username, vcCreator);
         VirtualCorpus vc = vcDao.retrieveVCByName(vcName, vcCreator);
         ParameterChecker.checkObjectValue(vcJson, "request entity");
@@ -280,8 +286,9 @@
                     deleteVCAccess(hiddenAccess.getId(), "system");
                     int groupId = hiddenAccess.getUserGroup().getId();
                     userGroupService.deleteAutoHiddenGroup(groupId, "system");
-                    // EM: should the users within the hidden group receive 
-                    // notifications? 
+                    // EM: should the users within the hidden group
+                    // receive
+                    // notifications?
                 }
                 // else remains the same
             }
@@ -318,24 +325,27 @@
     public void storeVC (QueryJson vc, String vcName, String createdBy)
             throws KustvaktException {
         String koralQuery = null;
-        if (vc.getQueryType().equals(QueryType.VIRTUAL_CORPUS)){
-            ParameterChecker.checkStringValue(vc.getCorpusQuery(), "corpusQuery");
+        if (vc.getQueryType().equals(QueryType.VIRTUAL_CORPUS)) {
+            ParameterChecker.checkStringValue(vc.getCorpusQuery(),
+                    "corpusQuery");
             koralQuery = serializeCorpusQuery(vc.getCorpusQuery());
         }
-        else if (vc.getQueryType().equals(QueryType.QUERY)){
+        else if (vc.getQueryType().equals(QueryType.QUERY)) {
             ParameterChecker.checkStringValue(vc.getQuery(), "query");
-            ParameterChecker.checkStringValue(vc.getQueryLanguage(), "queryLanguage");
+            ParameterChecker.checkStringValue(vc.getQueryLanguage(),
+                    "queryLanguage");
             koralQuery = serializeQuery(vc.getQuery(), vc.getQueryLanguage());
         }
-        
-        storeVC(vcName, vc.getType(), vc.getQueryType(), koralQuery, vc.getDefinition(),
-                vc.getDescription(), vc.getStatus(), vc.isCached(), createdBy);
+
+        storeVC(vcName, vc.getType(), vc.getQueryType(), koralQuery,
+                vc.getDefinition(), vc.getDescription(), vc.getStatus(),
+                vc.isCached(), createdBy);
     }
 
-    public void storeVC (String vcName, ResourceType type,
-            QueryType queryType, String koralQuery, String definition,
-            String description, String status, boolean isCached,
-            String username) throws KustvaktException {
+    public void storeVC (String vcName, ResourceType type, QueryType queryType,
+            String koralQuery, String definition, String description,
+            String status, boolean isCached, String username)
+            throws KustvaktException {
         ParameterChecker.checkNameValue(vcName, "vcName");
         ParameterChecker.checkObjectValue(type, "type");
 
@@ -398,12 +408,12 @@
         }
         return koralQuery;
     }
-    
+
     private String serializeQuery (String query, String queryLanguage)
             throws KustvaktException {
         QuerySerializer serializer = new QuerySerializer();
         String koralQuery;
-            koralQuery = serializer.setQuery(query, queryLanguage).toJSON();
+        koralQuery = serializer.setQuery(query, queryLanguage).toJSON();
         if (DEBUG) {
             jlog.debug(koralQuery);
         }
@@ -452,15 +462,14 @@
         return (numberOfDoc > 0) ? true : false;
     }
 
-
     public void shareVC (String username, String createdBy, String vcName,
             String groupName) throws KustvaktException {
 
         VirtualCorpus vc = vcDao.retrieveVCByName(vcName, createdBy);
-        if (vc == null){
+        if (vc == null) {
             String vcCode = createdBy + "/" + vcName;
             throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
-                    "Virtual corpus "+ vcCode+" is not found.",
+                    "Virtual corpus " + vcCode + " is not found.",
                     String.valueOf(vcCode));
         }
         if (!username.equals(vc.getCreatedBy())
@@ -469,7 +478,8 @@
                     "Unauthorized operation for user: " + username, username);
         }
 
-        UserGroup userGroup = userGroupService.retrieveUserGroupByName(groupName);
+        UserGroup userGroup =
+                userGroupService.retrieveUserGroupByName(groupName);
 
         if (!isVCAccessAdmin(userGroup, username)
                 && !adminDao.isAdmin(username)) {
@@ -494,9 +504,9 @@
                 throw new KustvaktException(StatusCodes.DB_INSERT_FAILED,
                         cause.getMessage());
             }
-            
-            vcDao.editVirtualCorpus(vc, null, ResourceType.PROJECT, null,
-                    null, null, null, null, vc.isCached());
+
+            vcDao.editVirtualCorpus(vc, null, ResourceType.PROJECT, null, null,
+                    null, null, null, vc.isCached());
         }
     }
 
@@ -528,7 +538,6 @@
     // }
     // }
 
-    
     public List<VirtualCorpusAccessDto> listVCAccessByUsername (String username)
             throws KustvaktException {
         List<VirtualCorpusAccess> accessList = new ArrayList<>();
@@ -536,17 +545,18 @@
             accessList = accessDao.retrieveAllAccess();
         }
         else {
-            List<UserGroup> groups = userGroupService.retrieveUserGroup(username);
-            for (UserGroup g: groups){
-                if (isVCAccessAdmin(g, username)){
-                    accessList.addAll(accessDao.retrieveActiveAccessByGroup(g.getId()));
-                }   
+            List<UserGroup> groups =
+                    userGroupService.retrieveUserGroup(username);
+            for (UserGroup g : groups) {
+                if (isVCAccessAdmin(g, username)) {
+                    accessList.addAll(
+                            accessDao.retrieveActiveAccessByGroup(g.getId()));
+                }
             }
         }
         return accessConverter.createVCADto(accessList);
     }
-    
-    
+
     public List<VirtualCorpusAccessDto> listVCAccessByVC (String username,
             String vcCreator, String vcName) throws KustvaktException {
 
@@ -587,17 +597,19 @@
 
         return accessConverter.createVCADto(accessList);
     }
-    
+
     public List<VirtualCorpusAccessDto> listVCAccessByGroup (String username,
             String groupName) throws KustvaktException {
-        UserGroup userGroup = userGroupService.retrieveUserGroupByName(groupName);
+        UserGroup userGroup =
+                userGroupService.retrieveUserGroupByName(groupName);
 
         List<VirtualCorpusAccess> accessList;
         if (adminDao.isAdmin(username)) {
             accessList = accessDao.retrieveAllAccessByGroup(userGroup.getId());
         }
         else if (isVCAccessAdmin(userGroup, username)) {
-            accessList = accessDao.retrieveActiveAccessByGroup(userGroup.getId());
+            accessList =
+                    accessDao.retrieveActiveAccessByGroup(userGroup.getId());
         }
         else {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
@@ -623,12 +635,12 @@
     }
 
     public VirtualCorpus searchVCByName (String username, String vcName,
-            String createdBy) throws KustvaktException {
+            String createdBy, QueryType queryType) throws KustvaktException {
         VirtualCorpus vc = vcDao.retrieveVCByName(vcName, createdBy);
         if (vc == null) {
             String vcCode = createdBy + "/" + vcName;
             throw new KustvaktException(StatusCodes.NO_RESOURCE_FOUND,
-                    "Virtual corpus "+ vcCode+" is not found.",
+                    queryType.displayName()+ " " + vcCode + " is not found.",
                     String.valueOf(vcCode));
         }
         checkVCAccess(vc, username);
@@ -636,11 +648,11 @@
     }
 
     public VirtualCorpusDto retrieveVCByName (String username, String vcName,
-            String createdBy) throws KustvaktException {
-        VirtualCorpus vc = searchVCByName(username, vcName, createdBy);
+            String createdBy, QueryType queryType) throws KustvaktException {
+        VirtualCorpus vc = searchVCByName(username, vcName, createdBy, queryType);
         String json = vc.getKoralQuery();
         String statistics = null;
-        if (vc.getQueryType().equals(QueryType.VIRTUAL_CORPUS)){
+        if (vc.getQueryType().equals(QueryType.VIRTUAL_CORPUS)) {
             statistics = krill.getStatistics(json);
         }
         return converter.createVirtualCorpusDto(vc, statistics);
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/QueryReferenceController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/QueryReferenceController.java
index ff8f35b..955de0e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/QueryReferenceController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/QueryReferenceController.java
@@ -1,11 +1,14 @@
 package de.ids_mannheim.korap.web.controller;
 
+import java.util.List;
+
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -119,7 +122,7 @@
         try {
             scopeService.verifyScope(context, OAuth2Scope.VC_INFO);
             return service.retrieveVCByName(context.getUsername(), qName,
-                    createdBy);
+                    createdBy, QueryType.QUERY);
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
@@ -159,6 +162,22 @@
 
     
     // TODO: List all queries available to the logged in user
+    @GET
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusDto> listAvailableQuery (
+            @Context SecurityContext securityContext,
+            @QueryParam("username") String username) {
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
+        try {
+            scopeService.verifyScope(context, OAuth2Scope.VC_INFO);
+            return service.listAvailableVCForUser(context.getUsername(),
+                    username, QueryType.QUERY);
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+    }
     // TODO: List all queries of a sepcific user
     // TODO: Some admin routes missing.
     // TODO: Some sharing routes missing
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
index 645329e..14b4ed2 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
@@ -23,6 +23,7 @@
 import com.sun.jersey.spi.container.ResourceFilters;
 
 import de.ids_mannheim.korap.constant.OAuth2Scope;
+import de.ids_mannheim.korap.constant.QueryType;
 import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.dto.VirtualCorpusAccessDto;
 import de.ids_mannheim.korap.dto.VirtualCorpusDto;
@@ -133,7 +134,7 @@
         try {
             scopeService.verifyScope(context, OAuth2Scope.VC_INFO);
             return service.retrieveVCByName(context.getUsername(), vcName,
-                    createdBy);
+                    createdBy, QueryType.VIRTUAL_CORPUS);
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
@@ -165,7 +166,7 @@
         try {
             scopeService.verifyScope(context, OAuth2Scope.VC_INFO);
             return service.listAvailableVCForUser(context.getUsername(),
-                    username);
+                    username, QueryType.VIRTUAL_CORPUS);
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
@@ -188,13 +189,14 @@
     @Path("~{createdBy}")
     @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
     public List<VirtualCorpusDto> listUserVC (
-            @PathParam("createdBy") String createdBy, 
+            @PathParam("createdBy") String createdBy,
             @Context SecurityContext securityContext) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
             scopeService.verifyScope(context, OAuth2Scope.VC_INFO);
-            return service.listOwnerVC(context.getUsername(), createdBy);
+            return service.listOwnerVC(context.getUsername(), createdBy,
+                    QueryType.VIRTUAL_CORPUS);
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
@@ -227,7 +229,8 @@
                 (TokenContext) securityContext.getUserPrincipal();
         try {
             scopeService.verifyScope(context, OAuth2Scope.ADMIN);
-            return service.listVCByType(context.getUsername(), createdBy, type);
+            return service.listVCByType(context.getUsername(), createdBy, type,
+                    QueryType.VIRTUAL_CORPUS);
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/input/QueryJson.java b/full/src/main/java/de/ids_mannheim/korap/web/input/QueryJson.java
index 0e312d7..8d061a9 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/input/QueryJson.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/input/QueryJson.java
@@ -23,7 +23,6 @@
     
     // required
     private ResourceType type;
-    private QueryType queryType;
     // required for queryType="VIRTUAL_CORPUS"
     private String corpusQuery;
     // required for queryType="QUERY"
@@ -35,4 +34,5 @@
     private String description;
     private String status;
     private String queryVersion;
+    private QueryType queryType;
 }
\ No newline at end of file
diff --git a/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql b/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql
index 6ec4b80..febf97b 100644
--- a/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql
+++ b/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql
@@ -69,7 +69,6 @@
   id INTEGER PRIMARY KEY AUTOINCREMENT,
   name VARCHAR(255) NOT NULL,
   type VARCHAR(100) NOT NULL,
-  query_type VARCHAR(100) NOT NULL,
   required_access VARCHAR(100) NOT NULL,
   created_by VARCHAR(100) NOT NULL,
   description VARCHAR(255) DEFAULT NULL,
diff --git a/full/src/main/resources/db/sqlite/V1.9__query_alteration.sql b/full/src/main/resources/db/sqlite/V1.9__query_alteration.sql
new file mode 100644
index 0000000..29a4368
--- /dev/null
+++ b/full/src/main/resources/db/sqlite/V1.9__query_alteration.sql
@@ -0,0 +1,2 @@
+ALTER TABLE virtual_corpus 
+ADD COLUMN query_type VARCHAR(100) NOT NULL;
\ No newline at end of file
diff --git a/full/src/main/resources/db/test/V3.7__insert_query_references.sql b/full/src/main/resources/db/test/V3.7__insert_query_references.sql
index e13b13b..3adf7bc 100644
--- a/full/src/main/resources/db/test/V3.7__insert_query_references.sql
+++ b/full/src/main/resources/db/test/V3.7__insert_query_references.sql
@@ -1,4 +1,8 @@
 -- query references
-INSERT INTO query_reference(name, type, required_access, created_by, description, status, query) 
-	VALUES ("dory-q", "PRIVATE", "FREE", "dory", "test query", "experimental",
+INSERT INTO virtual_corpus(name, type, query_type, required_access, created_by, description, status, corpus_query) 
+	VALUES ("dory-q", "PRIVATE", "QUERY", "FREE", "dory", "test query", "experimental",
+	'{ "@type": "koral:token" }');
+
+INSERT INTO virtual_corpus(name, type, query_type, required_access, created_by, description, status, corpus_query) 
+	VALUES ("system-q", "SYSTEM", "QUERY", "FREE", "system", "system query", "experimental",
 	'{ "@type": "koral:token" }');
diff --git a/full/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java b/full/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java
index 266a67f..c6b5c43 100644
--- a/full/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java
@@ -19,7 +19,7 @@
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.user.User;
 
-public class VirtualCorpusDaoTest extends SpringJerseyTest{
+public class VirtualCorpusDaoTest extends SpringJerseyTest {
 
     @Autowired
     private VirtualCorpusDao dao;
@@ -30,7 +30,7 @@
     @Test
     public void testListVCByType () throws KustvaktException {
         List<VirtualCorpus> vcList =
-                dao.retrieveVCByType(ResourceType.PUBLISHED, null);
+                dao.retrieveVCByType(ResourceType.PUBLISHED, null, QueryType.VIRTUAL_CORPUS);
         assertEquals(1, vcList.size());
 
         VirtualCorpus vc = vcList.get(0);
@@ -49,7 +49,7 @@
 
         // select vc
         List<VirtualCorpus> vcList =
-                dao.retrieveVCByType(ResourceType.SYSTEM, null);
+                dao.retrieveVCByType(ResourceType.SYSTEM, null, QueryType.VIRTUAL_CORPUS);
         assertEquals(2, vcList.size());
 
         VirtualCorpus vc = dao.retrieveVCById(id);
@@ -75,7 +75,7 @@
     @Test
     public void retrieveSystemVC () throws KustvaktException {
         List<VirtualCorpus> vc =
-                dao.retrieveVCByType(ResourceType.SYSTEM, null);
+                dao.retrieveVCByType(ResourceType.SYSTEM, null, QueryType.VIRTUAL_CORPUS);
         assertEquals(1, vc.size());
     }
 
@@ -86,7 +86,8 @@
      */
     @Test
     public void retrieveVCByUserDory () throws KustvaktException {
-        List<VirtualCorpus> virtualCorpora = dao.retrieveVCByUser("dory");
+        List<VirtualCorpus> virtualCorpora =
+                dao.retrieveVCByUser("dory", QueryType.VIRTUAL_CORPUS);
         // System.out.println(virtualCorpora);
         assertEquals(4, virtualCorpora.size());
         // ordered by id
@@ -105,7 +106,8 @@
      */
     @Test
     public void retrieveVCByUserNemo () throws KustvaktException {
-        List<VirtualCorpus> virtualCorpora = dao.retrieveVCByUser("nemo");
+        List<VirtualCorpus> virtualCorpora =
+                dao.retrieveVCByUser("nemo", QueryType.VIRTUAL_CORPUS);
         assertEquals(3, virtualCorpora.size());
         Iterator<VirtualCorpus> i = virtualCorpora.iterator();
         assertEquals("group-vc", i.next().getName());
@@ -121,7 +123,8 @@
      */
     @Test
     public void retrieveVCByUserMarlin () throws KustvaktException {
-        List<VirtualCorpus> virtualCorpora = dao.retrieveVCByUser("marlin");
+        List<VirtualCorpus> virtualCorpora =
+                dao.retrieveVCByUser("marlin", QueryType.VIRTUAL_CORPUS);
         assertEquals(3, virtualCorpora.size());
         Iterator<VirtualCorpus> i = virtualCorpora.iterator();
         assertEquals("system-vc", i.next().getName());
@@ -137,7 +140,8 @@
      */
     @Test
     public void retrieveVCByUserPearl () throws KustvaktException {
-        List<VirtualCorpus> virtualCorpora = dao.retrieveVCByUser("pearl");
+        List<VirtualCorpus> virtualCorpora =
+                dao.retrieveVCByUser("pearl", QueryType.VIRTUAL_CORPUS);
         assertEquals(2, virtualCorpora.size());
         Iterator<VirtualCorpus> i = virtualCorpora.iterator();
         assertEquals("system-vc", i.next().getName());
diff --git a/full/src/test/java/de/ids_mannheim/korap/rewrite/QueryRewriteTest.java b/full/src/test/java/de/ids_mannheim/korap/rewrite/QueryRewriteTest.java
index fd2b0ff..e780769 100644
--- a/full/src/test/java/de/ids_mannheim/korap/rewrite/QueryRewriteTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/rewrite/QueryRewriteTest.java
@@ -1,21 +1,16 @@
 package de.ids_mannheim.korap.rewrite;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
 
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.net.HttpHeaders;
 import com.sun.jersey.api.client.ClientResponse;
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.SpringJerseyTest;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.util.QueryException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
 /**
@@ -35,7 +30,22 @@
 
         String ent = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(ent);
-        assertEquals(node.at("/errors/0/1").asText(), "Query reference system/examplequery is not found.");
+        assertEquals("Query system/examplequery is not found.",
+                node.at("/errors/0/1").asText());
+    }
+    
+    @Test
+    public void testRewriteSystemQuery ()
+            throws KustvaktException, Exception {
+
+        ClientResponse response = resource().path(API_VERSION).path("search")
+            .queryParam("q", "[orth=der]{%23system-q} Baum")
+            .queryParam("ql", "poliqarp")
+            .get(ClientResponse.class);
+
+        String ent = response.getEntity(String.class);
+        System.out.println(ent);
+        JsonNode node = JsonUtils.readTree(ent);
     }
 
     @Test
diff --git a/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java
index a422b1c..31e51d8 100644
--- a/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java
@@ -96,7 +96,7 @@
 
         String vcName = "group-vc";
         VirtualCorpus existingVC =
-                vcService.searchVCByName(username, vcName, username);
+                vcService.searchVCByName(username, vcName, username, QueryType.VIRTUAL_CORPUS);
         QueryJson vcJson = new QueryJson();
         vcJson.setType(ResourceType.PUBLISHED);
 
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/QueryReferenceControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/QueryReferenceControllerTest.java
index 57c0df5..f4d90ef 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/QueryReferenceControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/QueryReferenceControllerTest.java
@@ -15,36 +15,54 @@
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
-public class QueryReferenceControllerTest extends SpringJerseyTest{
+public class QueryReferenceControllerTest extends SpringJerseyTest {
 
     private String testUser = "qRefControllerTest";
-    
+
     @Test
     public void testCreatePrivateQuery () throws KustvaktException {
-        String json = "{\"type\": \"PRIVATE\""
-                + ",\"queryType\": \"QUERY\""
-                + ",\"queryLanguage\": \"poliqarp\""
-                + ",\"query\": \"der\"}";
-        
-        String qName="new_query";
+        String json = "{\"type\": \"PRIVATE\"" + ",\"queryType\": \"QUERY\""
+                + ",\"queryLanguage\": \"poliqarp\"" + ",\"query\": \"der\"}";
+
+        String qName = "new_query";
         ClientResponse response = resource().path(API_VERSION).path("query")
-                .path("~"+testUser).path(qName)
+                .path("~" + testUser).path(qName)
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(testUser, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
                 .put(ClientResponse.class, json);
 
         assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
 
         JsonNode node = testRetrieveQueryByName(testUser, testUser, qName);
-        System.out.println(node);
+        assertEquals(qName, node.at("/name").asText());
+        assertEquals(ResourceType.PRIVATE.displayName(),
+                node.at("/type").asText());
+        assertEquals(testUser, node.at("/createdBy").asText());
     }
-    
-    
+
+    @Test
+    public void testListAvailableQuery () throws UniformInterfaceException,
+            ClientHandlerException, KustvaktException {
+        String username = "dory";
+        ClientResponse response = resource().path(API_VERSION).path("query")
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(username, "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        String entity = response.getEntity(String.class);
+//        System.out.println(entity);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(2, node.size());
+    }
+
     private JsonNode testRetrieveQueryByName (String username, String qCreator,
             String qName) throws UniformInterfaceException,
             ClientHandlerException, KustvaktException {
@@ -54,10 +72,10 @@
                         .createBasicAuthorizationHeaderValue(username, "pass"))
                 .get(ClientResponse.class);
         String entity = response.getEntity(String.class);
-//         System.out.println(entity);
+        // System.out.println(entity);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
 
         return JsonUtils.readTree(entity);
     }
-    
+
 }
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/QueryReferenceSearchTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/QueryReferenceSearchTest.java
new file mode 100644
index 0000000..8732aef
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/QueryReferenceSearchTest.java
@@ -0,0 +1,27 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.api.client.ClientResponse;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class QueryReferenceSearchTest {
+
+    /*@Test
+    public void testSearchWithVCRefEqual () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
+                .queryParam("cq", "referTo \"dory/dory-q\"")
+                .get(ClientResponse.class);
+
+        String ent = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(ent);
+        assertTrue(node.at("/matches").size() > 0);
+    }
+*/    
+}