DS_Store merge
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index c90977b..d3e5963 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -223,18 +223,6 @@
       <version>1.16.6</version>

       <scope>provided</scope>

     </dependency>

-    <dependency>

-      <groupId>com.restfuse</groupId>

-      <artifactId>com.eclipsesource.restfuse</artifactId>

-      <version>1.0.0</version>

-      <scope>provided</scope>

-      <exclusions>

-        <exclusion>

-          <artifactId>jetty-j2se6</artifactId>

-          <groupId>org.mortbay.jetty</groupId>

-        </exclusion>

-      </exclusions>

-    </dependency>

   </dependencies>

   <properties>

     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

diff --git a/pom.xml b/pom.xml
index d19d3c2..7be5f83 100644
--- a/pom.xml
+++ b/pom.xml
@@ -345,12 +345,12 @@
             <version>0.9.9-RC1</version>
         </dependency>
         <!-- deprecated? -->
-        <dependency>
-            <groupId>com.restfuse</groupId>
-            <artifactId>com.eclipsesource.restfuse</artifactId>
-            <version>1.0.0</version>
-            <scope>provided</scope>
-        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>com.restfuse</groupId>-->
+            <!--<artifactId>com.eclipsesource.restfuse</artifactId>-->
+            <!--<version>1.0.0</version>-->
+            <!--<scope>provided</scope>-->
+        <!--</dependency>-->
         <!-- deprecated -->
         <!--<dependency>-->
         <!--<groupId>com.jayway.restassured</groupId>-->
@@ -358,11 +358,11 @@
         <!--<version>2.4.0</version>-->
         <!--<scope>provided</scope>-->
         <!--</dependency>-->
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-core</artifactId>
-            <version>4.0.5.RELEASE</version>
-        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>org.springframework</groupId>-->
+            <!--<artifactId>spring-core</artifactId>-->
+            <!--<version>4.0.5.RELEASE</version>-->
+        <!--</dependency>-->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
diff --git a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
index 7cd0ecf..33b2398 100644
--- a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
+++ b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
@@ -82,7 +82,7 @@
         maxhits = new Integer(properties.getProperty("maxhits", "50000"));
         returnhits = new Integer(properties.getProperty("returnhits", "50000"));
         indexDir = properties.getProperty("lucene.indexDir", "");
-        port = new Integer(properties.getProperty("server.port", "8080"));
+        port = new Integer(properties.getProperty("server.port", "8095"));
         // server options
         serverHost = String
                 .valueOf(properties.getProperty("server.host", "localhost"));
@@ -180,9 +180,9 @@
             if (f.exists()) {
                 log4j.load(new FileInputStream(f));
                 PropertyConfigurator.configure(log4j);
-                jlog.warn(
+                jlog.info(
                         "using local logging properties file ({}) to configure logging system",
-                        "./config/log4j.properties");
+                        "./log4j.properties");
                 return;
             }
         }catch (Exception e) {
diff --git a/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java b/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java
index fe192db..99edf0e 100644
--- a/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java
+++ b/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java
@@ -41,20 +41,22 @@
     public Document findbyId(Integer id, User user) throws KustvaktException {
         MapSqlParameterSource s = new MapSqlParameterSource();
         s.addValue("id", id);
-        String sql = "select * from doc_store where id=:id";
+        String sql = "select id, persistent_id, disabled, strftime('%s', created) as created from doc_store where id=:id";
         try {
             return this.jdbcTemplate
                     .query(sql, s, new ResultSetExtractor<Document>() {
                         @Override
                         public Document extractData(ResultSet rs)
                                 throws SQLException, DataAccessException {
-                            Document doc = new Document(
-                                    rs.getString("persistent_id"));
-                            doc.setId(rs.getInt("id"));
-                            doc.setCreated(
-                                    rs.getTimestamp("created").getTime());
-                            doc.setDisabled(rs.getBoolean("disabled"));
-                            return doc;
+                            if (rs.isFirst()) {
+                                Document doc = new Document(
+                                        rs.getString("persistent_id"));
+                                doc.setId(rs.getInt("id"));
+                                doc.setCreated(rs.getLong("created"));
+                                doc.setDisabled(rs.getBoolean("disabled"));
+                                return doc;
+                            }
+                            return null;
                         }
                     });
         }catch (DataAccessException e) {
@@ -67,7 +69,7 @@
     public Document findbyId(String id, User user) throws KustvaktException {
         MapSqlParameterSource s = new MapSqlParameterSource();
         s.addValue("id", id);
-        String sql = "select id, persistent_id, strftime('%s', created) as created from doc_store where persistent_id=:id";
+        String sql = "select id, persistent_id, disabled, strftime('%s', created) as created from doc_store where persistent_id=:id";
 
         try {
             return this.jdbcTemplate
@@ -75,16 +77,18 @@
                         @Override
                         public Document extractData(ResultSet rs)
                                 throws SQLException, DataAccessException {
-                            Document doc = new Document(
-                                    rs.getString("persistent_id"));
-                            doc.setId(rs.getInt("id"));
-                            doc.setCreated(rs.getLong("created"));
-                            doc.setDisabled(rs.getBoolean("disabled"));
-                            return doc;
+                            if (!rs.isClosed()) {
+                                Document doc = new Document(
+                                        rs.getString("persistent_id"));
+                                doc.setId(rs.getInt("id"));
+                                doc.setCreated(rs.getLong("created"));
+                                doc.setDisabled(rs.getBoolean("disabled"));
+                                return doc;
+                            }
+                            return null;
                         }
                     });
         }catch (DataAccessException e) {
-            e.printStackTrace();
             throw new KustvaktException(StatusCodes.CONNECTION_ERROR);
         }
     }
@@ -124,12 +128,16 @@
                         @Override
                         public Document mapRow(ResultSet rs, int rowNum)
                                 throws SQLException {
-                            Document doc = new Document(
-                                    rs.getString("persistent_id"));
-                            doc.setId(rs.getInt("id"));
-                            doc.setCreated(rs.getLong("created"));
-                            doc.setDisabled(rs.getBoolean("disabled"));
-                            return doc;
+                            // todo: test on empty/closed resultset!
+                            if (!rs.isClosed()) {
+                                Document doc = new Document(
+                                        rs.getString("persistent_id"));
+                                doc.setId(rs.getInt("id"));
+                                doc.setCreated(rs.getLong("created"));
+                                doc.setDisabled(rs.getBoolean("disabled"));
+                                return doc;
+                            }
+                            return null;
                         }
                     });
         }catch (DataAccessException e) {
@@ -163,7 +171,6 @@
         try {
             return this.jdbcTemplate.update(sql, s);
         }catch (DataAccessException e) {
-            e.printStackTrace();
             throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
                     "illegal argument given", resource.getPersistentID());
         }
diff --git a/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java b/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
index cbc102d..bf3ab79 100644
--- a/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
+++ b/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
@@ -45,6 +45,9 @@
     @Override
     public UserSettings getUserSettings(Integer userid)
             throws KustvaktException {
+//        TransactionDefinition def = new DefaultTransactionDefinition();
+//        TransactionStatus status = transactionManager.getTransaction(def);
+
         MapSqlParameterSource np = new MapSqlParameterSource();
         np.addValue("us", userid);
         final String sql =
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/KustvaktEncryption.java b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/KustvaktEncryption.java
index a21d767..d4b8a31 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/KustvaktEncryption.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/KustvaktEncryption.java
@@ -5,6 +5,7 @@
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
 import edu.emory.mathcs.backport.java.util.Collections;
 import org.apache.commons.codec.EncoderException;
 import org.apache.commons.codec.binary.Base64;
@@ -15,7 +16,6 @@
 import org.owasp.esapi.errors.ValidationException;
 import org.owasp.esapi.reference.DefaultValidator;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Field;
@@ -31,7 +31,7 @@
 public class KustvaktEncryption implements EncryptionIface {
 
     private static final String ALGORITHM = "SHA-256";
-    private static Logger jlog = LoggerFactory
+    private static Logger jlog = KustvaktLogger
             .getLogger(KustvaktEncryption.class);
     // todo: disable this
     private static final String PASSWORD_SALT_FIELD = "accountCreation";
@@ -307,11 +307,9 @@
         return safeMap;
     }
 
-
     private String validateString(String descr, String input, String type,
             int length, boolean nullable) throws KustvaktException {
-        if (jlog.isDebugEnabled())
-            jlog.debug("validating string entry '{}'", input);
+        jlog.debug("validating string entry '{}'", input);
         String s;
         try {
             s = validator.getValidInput(descr, input, type, length, nullable);
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionCleanupFilter.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionCleanupFilter.java
index 74a5d06..6f12d59 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionCleanupFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionCleanupFilter.java
@@ -12,25 +12,12 @@
  * @author hanl
  * @date 28/07/2015
  */
-
-public class CollectionCleanupFilter implements RewriteTask.RewriteQuery {
-
-    // track path to operand
-    @Deprecated
-    private StringBuilder builder;
-
-    public CollectionCleanupFilter() {
-        super();
-    }
+public class CollectionCleanupFilter implements RewriteTask.RewriteNodeAt {
 
     @Override
     public JsonNode preProcess(KoralNode node, KustvaktConfiguration config,
             User user) {
-        if (node.has("collection")) {
-            JsonNode coll = node.rawNode().path("collection");
-            process(coll);
-        }
-        return null;
+        return process(node.rawNode());
     }
 
     private JsonNode process(JsonNode root) {
@@ -47,8 +34,10 @@
                 }
 
                 int count = node.size();
+                // remove group element and replace with single doc
                 if (count == 1)
                     sub = node.path(0);
+                    // indicate empty group
                 else if (count
                         == 0) // can't do anything here -- fixme: edge case?!
                     return null;
@@ -89,4 +78,9 @@
     public JsonNode postProcess(KoralNode node) {
         return null;
     }
+
+    @Override
+    public String at() {
+        return "/collection";
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionConstraint.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionConstraint.java
index 4e5edf2..d1630dd 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionConstraint.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionConstraint.java
@@ -13,12 +13,11 @@
  * @date 03/07/2015
  */
 // todo: test
-public class CollectionConstraint implements RewriteTask.RewriteNode {
+public class CollectionConstraint implements RewriteTask.IterableRewriteAt {
 
     @Override
     public JsonNode preProcess(KoralNode node, KustvaktConfiguration config,
             User user) {
-
         if (node.get("@type").equals("koral:doc")) {
             if (node.get("key").equals("corpusID") && !check(node, user)) {
                 node.removeNode();
@@ -52,4 +51,13 @@
         return corpus != null;
     }
 
+    @Override
+    public JsonNode postProcess(KoralNode node) {
+        return null;
+    }
+
+    @Override
+    public String path() {
+        return "collection";
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/DocMatchRewrite.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/DocMatchRewrite.java
index 079af47..cc58817 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/DocMatchRewrite.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/DocMatchRewrite.java
@@ -1,22 +1,65 @@
 package de.ids_mannheim.korap.resource.rewrite;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.handlers.DocumentDao;
+import de.ids_mannheim.korap.resources.Document;
+import de.ids_mannheim.korap.user.User;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
 
 /**
  * @author hanl
  * @date 12/11/2015
  */
-public class DocMatchRewrite implements RewriteTask.RewriteAfter {
+public class DocMatchRewrite implements RewriteTask.IterableRewriteAt {
 
+    private DocumentDao docDao;
+    private Cache cache;
 
+    public DocMatchRewrite() {
+        this.docDao = new DocumentDao(
+                BeanConfiguration.getBeans().getPersistenceClient());
+        this.cache = CacheManager.getInstance().getCache("documents");
+    }
 
     @Override
     public JsonNode postProcess(KoralNode node) {
+        Document doc = null;
 
+        if (node.has("docID")) {
+            String docID = node.get("docID");
+            Element e = this.cache.get(docID);
+            if (e == null) {
+                try {
+                    doc = docDao.findbyId(docID, null);
+                }catch (KustvaktException ex) {
+                    ex.printStackTrace();
+                    // todo: what to do here?!
+                }
 
+                if (doc != null)
+                    this.cache.put(new Element(docID, doc));
+            }else
+                doc = (Document) e.getObjectValue();
 
+            if (doc != null && doc.isDisabled())
+                node.removeNode();
+        }
+        return node.rawNode();
+    }
 
+    @Override
+    public String path() {
+        return "matches";
+    }
 
+    @Override
+    public JsonNode preProcess(KoralNode node, KustvaktConfiguration config,
+            User user) {
         return null;
     }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/FoundryInject.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/FoundryInject.java
index 14482d1..eebc92c 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/FoundryInject.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/FoundryInject.java
@@ -9,11 +9,8 @@
  * @author hanl
  * @date 30/06/2015
  */
-public class FoundryInject implements RewriteTask.RewriteNode {
+public class FoundryInject implements RewriteTask.IterableRewriteAt {
 
-    public FoundryInject() {
-        super();
-    }
 
     @Override
     public JsonNode preProcess(KoralNode node, KustvaktConfiguration config,
@@ -35,4 +32,14 @@
         }
         return node.rawNode();
     }
+
+    @Override
+    public String path() {
+        return "query";
+    }
+
+    @Override
+    public JsonNode postProcess(KoralNode node) {
+        return null;
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/IdWriter.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/IdWriter.java
index f35597f..737cbe4 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/IdWriter.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/IdWriter.java
@@ -1,7 +1,6 @@
 package de.ids_mannheim.korap.resource.rewrite;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.user.User;
 
@@ -14,9 +13,7 @@
     private int counter;
 
     public IdWriter() {
-        super();
         this.counter = 0;
-
     }
 
     @Override
@@ -27,21 +24,9 @@
             if (s != null && !s.isEmpty())
                 node.put("idn", s + "_" + counter++);
         }
-
         return node.rawNode();
     }
 
-    @Deprecated
-    private JsonNode addId(JsonNode node) {
-        if (node.isObject()) {
-            ObjectNode o = (ObjectNode) node;
-            String s = extractToken(node);
-            if (s != null && !s.isEmpty())
-                o.put("idn", s + "_" + counter++);
-        }
-        return node;
-    }
-
     // fixme: koral token --> how does grouping behave?!
     private String extractToken(JsonNode token) {
         JsonNode wrap = token.path("wrap");
@@ -49,4 +34,5 @@
             return wrap.path("key").asText();
         return null;
     }
+
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java
index 017de70..94dd6c7 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java
@@ -18,18 +18,26 @@
     private JsonNode node;
     private KoralRewriteBuilder builder;
     private boolean remove;
+    private final String target;
 
-    private KoralNode(JsonNode node) {
+    private KoralNode(String target, JsonNode node) {
         this.node = node;
+        this.target = target;
         this.builder = new KoralRewriteBuilder();
         this.remove = false;
     }
 
     public static KoralNode wrapNode(JsonNode node) {
-        return new KoralNode(node) {
+        return new KoralNode(null, node) {
         };
     }
 
+    @Override
+    public String toString() {
+        return this.node.toString();
+    }
+
+    @Deprecated
     public boolean setNode(Object path) {
         JsonNode n = null;
         if (this.node.isObject() && this.node.has((String) path))
@@ -91,6 +99,10 @@
         return null;
     }
 
+    public JsonNode at(String name) {
+        return this.node.at(name);
+    }
+
     public boolean has(Object ident) {
         if (ident instanceof String)
             return this.node.has((String) ident);
@@ -107,10 +119,14 @@
         this.remove = true;
     }
 
-    public boolean toRemove() {
+    public boolean isRemove() {
         return this.remove;
     }
 
+    public final String target() {
+        return this.target;
+    }
+
     //todo: 21.10.15 -- redo with better return policies!
     private static class KoralRewriteBuilder {
 
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/MetaConstraint.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/MetaConstraint.java
index 8dddf4f..00aa844 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/MetaConstraint.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/MetaConstraint.java
@@ -8,15 +8,13 @@
  * @author hanl
  * @date 04/07/2015
  */
-public class MetaConstraint implements RewriteTask.RewriteQuery {
+public class MetaConstraint implements RewriteTask.RewriteNodeAt {
 
-    public MetaConstraint() {
-        super();
-    }
 
     @Override
     public JsonNode preProcess(KoralNode node, KustvaktConfiguration config,
             User user) {
+        // redundant
         if (node.rawNode().has("meta")) {
             JsonNode meta = node.rawNode().path("meta");
             //todo: check meta parameter
@@ -29,4 +27,10 @@
     public JsonNode postProcess(KoralNode node) {
         return null;
     }
+
+
+    @Override
+    public String at() {
+        return "/meta";
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java
index 350bebc..03b77ec 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/PublicCollection.java
@@ -15,7 +15,7 @@
  * @date 04/07/2015
  */
 // todo: 11.11.15
-public class PublicCollection implements RewriteTask.RewriteQuery {
+public class PublicCollection implements RewriteTask.RewriteNodeAt {
 
     public PublicCollection() {
         super();
@@ -26,6 +26,7 @@
     public JsonNode preProcess(KoralNode node, KustvaktConfiguration config,
             User user) {
         JsonNode subnode = node.rawNode();
+        // todo: test
         if (!subnode.at("/collection").findValuesAsText("key")
                 .contains("corpusID")) {
             //todo: inject public collection node
@@ -54,4 +55,9 @@
     public JsonNode postProcess(KoralNode node) {
         return null;
     }
+
+    @Override
+    public String at() {
+        return "/collection";
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteHandler.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteHandler.java
index 49cef0c..b16d65c 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteHandler.java
@@ -9,9 +9,7 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.*;
 
 /**
  * @author hanl
@@ -22,9 +20,14 @@
 public class RewriteHandler {
 
     private static Logger jlog = KustvaktLogger.getLogger(RewriteHandler.class);
-    private Collection<RewriteTask> node_processors;
+    private Collection<RewriteTask.IterableRewriteAt> node_processors;
     private Collection<RewriteTask.RewriteKoralToken> token_node_processors;
-    private Collection<RewriteTask.RewriteQuery> query_processors;
+    private Collection<RewriteTask> query_processors;
+
+    //    private Collection<RewriteTask.RewriteNode2> fixed_nodes;
+    //    private Collection<RewriteTask.IterableRewrite> iterable_nodes;
+
+    private Set<Class> failed_task_registration;
 
     private KustvaktConfiguration config;
 
@@ -34,24 +37,39 @@
         this.node_processors = new HashSet<>();
         this.token_node_processors = new HashSet<>();
         this.query_processors = new HashSet<>();
+        this.failed_task_registration = new HashSet<>();
     }
 
     public boolean addProcessor(RewriteTask rewriter) {
         if (rewriter instanceof RewriteTask.RewriteKoralToken)
             return this.token_node_processors
                     .add((RewriteTask.RewriteKoralToken) rewriter);
-        else if (rewriter instanceof RewriteTask.RewriteQuery)
-            return this.query_processors
-                    .add((RewriteTask.RewriteQuery) rewriter);
+        else if (rewriter instanceof RewriteTask.IterableRewriteAt)
+            return this.node_processors
+                    .add((RewriteTask.IterableRewriteAt) rewriter);
         else if (rewriter instanceof RewriteTask.RewriteBefore
                 | rewriter instanceof RewriteTask.RewriteAfter)
-            return this.node_processors.add(rewriter);
-        //        else if (rewriter instanceof RewriteTask.RewriteAfter)
-        //            return this.node_post_processors
-        //                    .add((RewriteTask.RewriteAfter) rewriter);
+            return this.query_processors.add(rewriter);
+
+        this.failed_task_registration.add(rewriter.getClass());
         return false;
     }
 
+    public boolean addProcessor2(RewriteTask rewriteTask) {
+        //        if (rewriteTask instanceof RewriteTask.RewriteNode2)
+        //            return this.fixed_nodes.add((RewriteTask.RewriteNode2) rewriteTask);
+        //        else if (rewriteTask instanceof RewriteTask.IterableRewrite)
+        //            return this.iterable_nodes
+        //                    .add((RewriteTask.IterableRewrite) rewriteTask);
+        //        else if (rewriteTask instanceof RewriteTask.RewriteBefore)
+        // gets the entire pre processed query injected.
+        return false;
+    }
+
+    public final Collection<Class> getFailedHandlers() {
+        return this.failed_task_registration;
+    }
+
     @Override
     public String toString() {
         StringBuilder b = new StringBuilder();
@@ -78,6 +96,7 @@
             task = (RewriteTask) c.newInstance();
         }catch (NoSuchMethodException | InvocationTargetException
                 | IllegalAccessException | InstantiationException e) {
+            this.failed_task_registration.add(rewriter);
             return false;
         }
         return addProcessor(task);
@@ -89,60 +108,57 @@
         this.token_node_processors.clear();
     }
 
-    private boolean process(JsonNode root, User user, boolean post) {
+    private boolean process(String name, JsonNode root, User user,
+            boolean post) {
         if (root.isObject()) {
             if (root.has("operands")) {
                 JsonNode ops = root.at("/operands");
                 Iterator<JsonNode> it = ops.elements();
                 while (it.hasNext()) {
-                    JsonNode n = it.next();
-                    if (process(n, user, post)) {
+                    JsonNode next = it.next();
+                    if (process(name, next, user, post))
                         it.remove();
-                    }
                 }
-
             }else if (root.path("@type").asText().equals("koral:token")) {
                 // todo: koral:token nodes cannot be flagged for deletion --> creates the possibility for empty koral:token nodes
-                processNode(KoralNode.wrapNode(root), user,
+                processNode(name, KoralNode.wrapNode(root), user,
                         this.token_node_processors, post);
-                return process(root.path("wrap"), user, post);
+                return process(name, root.path("wrap"), user, post);
             }else {
-                return processNode(KoralNode.wrapNode(root), user,
+                return processNode(name, KoralNode.wrapNode(root), user,
                         this.node_processors, post);
             }
         }else if (root.isArray()) {
-            //todo: test!
             Iterator<JsonNode> it = root.elements();
             while (it.hasNext()) {
-                JsonNode n = it.next();
-                if (process(n, user, post)) {
+                JsonNode next = it.next();
+                if (process(name, next, user, post))
                     it.remove();
-                }
             }
         }
         return false;
     }
 
-    public JsonNode preProcess(JsonNode root, User user) {
-        boolean post = false;
-        for (JsonNode n : root)
-            process(n, user, post);
-        processNode(KoralNode.wrapNode(root), user, this.query_processors,
-                post);
+    private JsonNode process(JsonNode root, User user, boolean post) {
+        Iterator<Map.Entry<String, JsonNode>> it = root.fields();
+        while (it.hasNext()) {
+            Map.Entry<String, JsonNode> next = it.next();
+            process(next.getKey(), next.getValue(), user, post);
+        }
+        processFixedNode(root, user, this.query_processors, post);
         return root;
     }
 
+    public JsonNode preProcess(JsonNode root, User user) {
+        return process(root, user, false);
+    }
+
     public String preProcess(String json, User user) {
         return JsonUtils.toJSON(preProcess(JsonUtils.readTree(json), user));
     }
 
     public JsonNode postProcess(JsonNode root, User user) {
-        boolean post = true;
-        for (JsonNode n : root)
-            process(n, user, post);
-        processNode(KoralNode.wrapNode(root), user, this.query_processors,
-                post);
-        return root;
+        return process(root, user, true);
     }
 
     public String postProcess(String json, User user) {
@@ -156,22 +172,50 @@
      * @return boolean true if node is to be removed from parent! Only applies if parent is an array node
      */
     // todo: integrate notifications into system!
-    private boolean processNode(KoralNode node, User user,
+    private boolean processNode(String rootNode, KoralNode node, User user,
             Collection<? extends RewriteTask> tasks, boolean post) {
         for (RewriteTask task : tasks) {
-            if (jlog.isDebugEnabled()) {
-                jlog.debug("running processor on node " + node);
-                jlog.debug("on processor " + task.getClass().toString());
+            jlog.debug("running processor on node: " + node);
+            jlog.debug("on processor: " + task.getClass().toString());
+
+            if (task instanceof RewriteTask.IterableRewriteAt) {
+                RewriteTask.IterableRewriteAt rw = (RewriteTask.IterableRewriteAt) task;
+                if (rw.path() != null && !rw.path().equals(rootNode)) {
+                    jlog.debug("skipping node: " + node);
+                    continue;
+                }
             }
-            if (task instanceof RewriteTask.RewriteBefore)
+
+            if (!post && task instanceof RewriteTask.RewriteBefore)
                 ((RewriteTask.RewriteBefore) task)
                         .preProcess(node, this.config, user);
-            if (post && task instanceof RewriteTask.RewriteAfter)
+            else if (task instanceof RewriteTask.RewriteAfter)
                 ((RewriteTask.RewriteAfter) task).postProcess(node);
-            if (node.toRemove())
+
+            if (node.isRemove())
                 break;
         }
-        return node.toRemove();
+        return node.isRemove();
+    }
+
+    private void processFixedNode(JsonNode node, User user,
+            Collection<RewriteTask> tasks, boolean post) {
+        for (RewriteTask task : tasks) {
+            JsonNode next = node;
+            if (task instanceof RewriteTask.RewriteNodeAt) {
+                RewriteTask.RewriteNodeAt rwa = (RewriteTask.RewriteNodeAt) task;
+                if ((rwa.at() != null && !node.at(rwa.at()).isMissingNode()))
+                    next = node.at(rwa.at());
+            }
+
+            if (!post && task instanceof RewriteTask.RewriteBefore)
+                ((RewriteTask.RewriteBefore) task)
+                        .preProcess(KoralNode.wrapNode(next), this.config,
+                                user);
+            else
+                ((RewriteTask.RewriteAfter) task)
+                        .postProcess(KoralNode.wrapNode(next));
+        }
     }
 
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteTask.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteTask.java
index 17683ce..47b65ae 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteTask.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteTask.java
@@ -21,26 +21,30 @@
                 User user);
     }
 
+    /**
+     * Post processor targeted at result sets for queries
+     * {@link de.ids_mannheim.korap.resource.rewrite.RewriteTask.RewriteAfter} queries will run
+     * after {@link de.ids_mannheim.korap.resource.rewrite.RewriteTask.IterableRewriteAt} have been processed
+     */
     interface RewriteAfter extends RewriteTask {
         JsonNode postProcess(KoralNode node);
     }
 
     /**
-     * query rewrites get injected the entire query from root containing all child nodes
-     * <p/>
-     * {@link RewriteQuery} does not allow the deletion of the root node or subnode through KoralNode.
-     * The {@link de.ids_mannheim.korap.resource.rewrite.RewriteHandler} will igonore respecitve invalid requests
+     * nodes subject to rewrites at fixed json pointer location.
+     * Json-pointer based rewrites are processed after iterable rewrites
+     * Deletion via KoralNode not allowed. Supports pre- and post-processing
      */
-    interface RewriteQuery extends RewriteBefore, RewriteAfter {
+    interface RewriteNodeAt extends RewriteBefore, RewriteAfter {
+        String at();
     }
 
     /**
-     * Koral term nodes that are subject to rewrites
-     * Be aware that node rewrites are processed before query rewrites. Thus query rewrite may override previous node rewrites
-     * <p/>
-     * {@link RewriteNode} rewrite supports the deletion of the respective node by simply setting the node invalid in KoralNode
+     * terminal object nodes that are subject to rewrites through node iteration
+     * (both object and array node iteration supported)
      */
-    interface RewriteNode extends RewriteBefore {
+    interface IterableRewriteAt extends RewriteBefore, RewriteAfter {
+        String path();
     }
 
     /**
@@ -50,4 +54,25 @@
      */
     interface RewriteKoralToken extends RewriteBefore {
     }
+
+    /**
+     * query rewrites get injected the entire query from root containing all child nodes
+     * <p/>
+     * {@link RewriteQuery} does not allow the deletion of the root node or subnode through KoralNode.
+     * The {@link de.ids_mannheim.korap.resource.rewrite.RewriteHandler} will igonore respecitve invalid requests
+     */
+    @Deprecated
+    interface RewriteQuery extends RewriteBefore, RewriteAfter {
+    }
+
+    /**
+     * Koral term nodes that are subject to rewrites
+     * Be aware that node rewrites are processed before query rewrites. Thus query rewrite may override previous node rewrites
+     * <p/>
+     * {@link RewriteNode} rewrite supports the deletion of the respective node by simply setting the node invalid in KoralNode
+     */
+    @Deprecated
+    interface RewriteNode extends RewriteBefore {
+    }
+
 }
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/TreeConstraint.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/TreeConstraint.java
index e96b3fe..2e56999 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/TreeConstraint.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/TreeConstraint.java
@@ -42,7 +42,7 @@
  * @author hanl
  * @date 02/07/2015
  */
-public class TreeConstraint implements RewriteTask.RewriteQuery {
+public class TreeConstraint implements RewriteTask.RewriteNodeAt {
 
     private String pointer;
 
@@ -62,4 +62,9 @@
     public JsonNode postProcess(KoralNode node) {
         return null;
     }
+
+    @Override
+    public String at() {
+        return null;
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java b/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java
index 78d0a44..c3e3cee 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/ResourceHandler.java
@@ -58,7 +58,6 @@
         } catch (EmptyResultException e) {
             throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED);
         }
-
         return p.getResource();
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/utils/KustvaktLogger.java b/src/main/java/de/ids_mannheim/korap/utils/KustvaktLogger.java
index 1a5c7a9..63d4533 100644
--- a/src/main/java/de/ids_mannheim/korap/utils/KustvaktLogger.java
+++ b/src/main/java/de/ids_mannheim/korap/utils/KustvaktLogger.java
@@ -28,13 +28,12 @@
     private Logger log;
 
     public static KustvaktLogger getLogger(Class cl) {
-        KustvaktLogger l = new KustvaktLogger(LoggerFactory.getLogger(cl));
-        return l;
+        return new KustvaktLogger(LoggerFactory.getLogger(cl));
     }
 
     public static KustvaktLogger getLogger(String name) {
-        KustvaktLogger l = new KustvaktLogger(LoggerFactory.getLogger(name));
-        return l;
+        return new KustvaktLogger(LoggerFactory.getLogger(name));
+
     }
 
     private KustvaktLogger(Logger log) {
diff --git a/src/main/resources/default-config.xml b/src/main/resources/default-config.xml
index 4117b76..3f9f6a6 100644
--- a/src/main/resources/default-config.xml
+++ b/src/main/resources/default-config.xml
@@ -61,20 +61,21 @@
     </bean>
 
     <!--class="org.apache.commons.dbcp2.BasicDataSource"-->
+    <!-- org.springframework.jdbc.datasource.SingleConnectionDataSource -->
     <bean id="dataSource"
-          class="org.springframework.jdbc.datasource.SingleConnectionDataSource"
+          class="org.apache.commons.dbcp2.BasicDataSource"
           lazy-init="true">
         <property name="driverClassName" value="${jdbc.driverClassName}"/>
         <property name="url" value="${jdbc.url}"/>
         <property name="username" value="${jdbc.username}"/>
         <property name="password" value="${jdbc.password}"/>
         <!-- relevant for single connection datasource and sqlite -->
-        <property name="suppressClose">
-            <value>true</value>
-        </property>
-        <!--<property name="initialSize" value="1"/>-->
-        <!--<property name="maxIdle" value="1"/>-->
-        <!--<property name="poolPreparedStatements" value="true"/>-->
+        <!--<property name="suppressClose">-->
+        <!--<value>true</value>-->
+        <!--</property>-->
+        <property name="initialSize" value="2"/>
+        <property name="maxIdle" value="2"/>
+        <property name="poolPreparedStatements" value="true"/>
     </bean>
 
     <!-- to configure database for sqlite, mysql, etc. migrations -->
diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml
index 3265324..34f478c 100644
--- a/src/main/resources/ehcache.xml
+++ b/src/main/resources/ehcache.xml
@@ -2,6 +2,12 @@
          xsi:noNamespaceSchemaLocation='http://ehcache.org/ehcache.xsd'>
     <defaultCache eternal='true' overflowToDisk='false'/>
     <!--maxBytesLocalHeap="200M"-->
+    <cache name="documents"
+           timeToIdleSeconds="172800"
+           eternal='false'
+           memoryStoreEvictionPolicy="LRU"
+           maxEntriesLocalHeap="2000"
+           overflowToDisk='false'/>
     <cache name='users'
            timeToIdleSeconds="172800"
            eternal='false'
diff --git a/src/test/java/CollectionRewriteTest.java b/src/test/java/CollectionRewriteTest.java
index 995cdf7..d115455 100644
--- a/src/test/java/CollectionRewriteTest.java
+++ b/src/test/java/CollectionRewriteTest.java
@@ -27,7 +27,7 @@
 
     @BeforeClass
     public static void init() {
-        BeanConfiguration.loadClasspathContext("default-config.xml");
+        BeanConfiguration.loadClasspathContext("test-config.xml");
         config = BeanConfiguration.getBeans().getConfiguration();
     }
 
@@ -36,13 +36,13 @@
         BeanConfiguration.closeApplication();
     }
 
+    @Deprecated
     @Test
     public void test2() {
         Pattern p = Pattern.compile("([\\.\\w]+)\\((.+)\\)");
         String cl = de.ids_mannheim.korap.security.ac.SecurityManager.class
                 .getCanonicalName();
         Matcher m = p.matcher(cl);
-        System.out.println("FOUND SOMETHING?! " + m.find());
         while (m.find())
             System.out.println("group 1 " + m.group(1));
 
@@ -56,8 +56,8 @@
         s.setQuery(simple_add_query, "poliqarp");
         s.setCollection("textClass=politik & corpusID=WPD");
         String result = s.toJSON();
-        JsonNode node = JsonUtils.readTree(
-                handler.preProcess(result, User.UserFactory.getUser("test_user")));
+        JsonNode node = JsonUtils.readTree(handler.preProcess(result,
+                User.UserFactory.getUser("test_user")));
         assert node != null;
         assert node.at("/collection/operands").size() == 1;
     }
@@ -70,9 +70,9 @@
         s.setQuery(simple_add_query, "poliqarp");
         s.setCollection("corpusID=BRZ13 & corpusID=WPD");
         String result = s.toJSON();
-        JsonNode node = JsonUtils.readTree(
-                handler.preProcess(result, User.UserFactory.getUser("test_user")));
-        System.out.println("RESULTING REWR NODE " + node);
+        JsonNode node = JsonUtils.readTree(handler.preProcess(result,
+                User.UserFactory.getUser("test_user")));
+        //        System.out.println("RESULTING REWR NODE " + node);
         assert node != null;
         assert node.at("/collection/operands").size() == 0;
     }
@@ -86,10 +86,9 @@
         s.setCollection(
                 "(corpusID=BRZ13 & textClass=Wissenschaft) & corpusID=WPD");
         String result = s.toJSON();
-        JsonNode node = JsonUtils.readTree(
-                handler.preProcess(result, User.UserFactory.getUser("test_user")));
+        JsonNode node = JsonUtils.readTree(handler.preProcess(result,
+                User.UserFactory.getUser("test_user")));
 
-        System.out.println("COLLECTION NODE " + result);
         assert node != null;
         assert node.at("/collection/operands/0/@type").asText()
                 .equals("koral:docGroup");
@@ -108,8 +107,9 @@
         s.setCollection(
                 "(corpusID=BRZ13 & corpusID=WPD) & textClass=Wissenschaft & textClass=Sport");
         String result = s.toJSON();
-        JsonNode node = JsonUtils.readTree(
-                handler.preProcess(result, User.UserFactory.getUser("test_user")));
+        JsonNode node = JsonUtils.readTree(handler.preProcess(result,
+                User.UserFactory.getUser("test_user")));
+
         assert node != null;
         assert node.at("/collection/@type").asText().equals("koral:docGroup");
         assert node.at("/collection/operands").size() == 2;
@@ -128,8 +128,8 @@
         s.setQuery(simple_add_query, "poliqarp");
         s.setCollection("(corpusID=BRZ13 & textClass=Wissenschaft)");
         String result = s.toJSON();
-        JsonNode node = JsonUtils.readTree(
-                handler.preProcess(result, User.UserFactory.getUser("test_user")));
+        JsonNode node = JsonUtils.readTree(handler.preProcess(result,
+                User.UserFactory.getUser("test_user")));
         assert node != null;
         assert node.at("/collection/@type").asText().equals("koral:doc");
     }
@@ -144,8 +144,8 @@
         s.setCollection(
                 "(corpusID=BRZ13 & corpusID=WPD) & textClass=Wissenschaft");
         String result = s.toJSON();
-        JsonNode node = JsonUtils.readTree(
-                handler.preProcess(result, User.UserFactory.getUser("test_user")));
+        JsonNode node = JsonUtils.readTree(handler.preProcess(result,
+                User.UserFactory.getUser("test_user")));
 
         assert node != null;
         assert node.at("/collection/@type").asText().equals("koral:doc");
@@ -162,13 +162,15 @@
         s.setCollection(
                 "(docID=random & textClass=Wissenschaft) & corpusID=WPD");
         String result = s.toJSON();
-        JsonNode node = JsonUtils.readTree(
-                handler.preProcess(result, User.UserFactory.getUser("test_user")));
+        JsonNode node = JsonUtils.readTree(handler.preProcess(result,
+                User.UserFactory.getUser("test_user")));
         System.out.println("original node " + result);
         System.out.println("result node " + node);
         assert node != null;
         assert node.at("/collection/@type").asText().equals("koral:docGroup");
         assert node.at("/collection/operands").size() == 2;
+        assert node.at("/collection/operands/0/@type").asText()
+                .equals("koral:doc");
     }
 
 }
diff --git a/src/test/java/de/ids_mannheim/korap/config/ClassLoaderTest.java b/src/test/java/de/ids_mannheim/korap/config/ClassLoaderTest.java
index 94ff6a2..3c18c93 100644
--- a/src/test/java/de/ids_mannheim/korap/config/ClassLoaderTest.java
+++ b/src/test/java/de/ids_mannheim/korap/config/ClassLoaderTest.java
@@ -16,11 +16,11 @@
     @After
     public void close() {
         BeanConfiguration.closeApplication();
-    }
+    }    
 
     @Test
     public void testBeanConfigurationLoaderThrowsNoException() {
-        BeanConfiguration.loadClasspathContext("default-config.xml");
+        BeanConfiguration.loadClasspathContext("test-config.xml");
         assert BeanConfiguration.hasContext();
     }
 
diff --git a/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java b/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java
index 2c11019..d098502 100644
--- a/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java
+++ b/src/test/java/de/ids_mannheim/korap/config/ConfigTest.java
@@ -51,7 +51,7 @@
 
     @Test(expected = KustvaktException.class)
     public void testBeanOverrideInjection() throws KustvaktException {
-        BeanConfiguration.loadClasspathContext("default-config.xml");
+        BeanConfiguration.loadClasspathContext("test-config.xml");
 
         BeanConfiguration.getBeans().getConfiguration().setPropertiesAsStream(
                 ConfigTest.class.getClassLoader()
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/KustvaktCoreRestTest.java b/src/test/java/de/ids_mannheim/korap/web/service/KustvaktCoreRestTest.java
index 7af97ea..d8bf7df 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/KustvaktCoreRestTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/KustvaktCoreRestTest.java
@@ -16,6 +16,7 @@
  * @author hanl
  * @date 26/06/2015
  */
+//todo: check tranferable index config path for test cases
 public class KustvaktCoreRestTest extends FastJerseyTest {
 
     @BeforeClass
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/OAuth2EndpointTest.java b/src/test/java/de/ids_mannheim/korap/web/service/OAuth2EndpointTest.java
index 560d66a..847b875 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/OAuth2EndpointTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/OAuth2EndpointTest.java
@@ -22,7 +22,7 @@
 
     @BeforeClass
     public static void configure() {
-        BeanConfiguration.loadClasspathContext("default-config.xml");
+        BeanConfiguration.loadClasspathContext("test-config.xml");
         setPackages("de.ids_mannheim.korap.web.service",
                 "de.ids_mannheim.korap.web.filter",
                 "de.ids_mannheim.korap.web.utils");
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/OAuth2HandlerTest.java b/src/test/java/de/ids_mannheim/korap/web/service/OAuth2HandlerTest.java
index f0d3d2a..f0411f7 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/OAuth2HandlerTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/OAuth2HandlerTest.java
@@ -29,7 +29,7 @@
 
     @BeforeClass
     public static void setup() throws KustvaktException {
-        BeanConfiguration.loadClasspathContext("default-config.xml");
+        BeanConfiguration.loadClasspathContext("test-config.xml");
         handler = new OAuth2Handler(
                 BeanConfiguration.getBeans().getPersistenceClient());
         crypto = BeanConfiguration.getBeans().getEncryption();