higher performance implementation for rewrite handler, test suite for rest functions, fast jersey junit tester, rewrite test suite
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index 3054681..5241316 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -88,46 +88,6 @@
         </exclusion>

       </exclusions>

     </dependency>

-    <dependency>

-      <groupId>com.jayway.restassured</groupId>

-      <artifactId>rest-assured</artifactId>

-      <version>2.4.0</version>

-      <scope>provided</scope>

-      <exclusions>

-        <exclusion>

-          <artifactId>groovy</artifactId>

-          <groupId>org.codehaus.groovy</groupId>

-        </exclusion>

-        <exclusion>

-          <artifactId>groovy-xml</artifactId>

-          <groupId>org.codehaus.groovy</groupId>

-        </exclusion>

-        <exclusion>

-          <artifactId>httpclient</artifactId>

-          <groupId>org.apache.httpcomponents</groupId>

-        </exclusion>

-        <exclusion>

-          <artifactId>httpmime</artifactId>

-          <groupId>org.apache.httpcomponents</groupId>

-        </exclusion>

-        <exclusion>

-          <artifactId>hamcrest-library</artifactId>

-          <groupId>org.hamcrest</groupId>

-        </exclusion>

-        <exclusion>

-          <artifactId>tagsoup</artifactId>

-          <groupId>org.ccil.cowan.tagsoup</groupId>

-        </exclusion>

-        <exclusion>

-          <artifactId>json-path</artifactId>

-          <groupId>com.jayway.restassured</groupId>

-        </exclusion>

-        <exclusion>

-          <artifactId>xml-path</artifactId>

-          <groupId>com.jayway.restassured</groupId>

-        </exclusion>

-      </exclusions>

-    </dependency>

   </dependencies>

   <properties>

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

diff --git a/pom.xml b/pom.xml
index 795fc83..2e28fb8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -105,6 +105,16 @@
             <version>1.8</version>
         </dependency>
         <dependency>
+            <groupId>com.sun.jersey.jersey-test-framework</groupId>
+            <artifactId>jersey-test-framework-core</artifactId>
+            <version>1.19</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey.jersey-test-framework</groupId>
+            <artifactId>jersey-test-framework-grizzly</artifactId>
+            <version>1.19</version>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.7.5</version>
@@ -142,7 +152,7 @@
         <dependency>
             <groupId>de.ids_mannheim.korap</groupId>
             <artifactId>Koral</artifactId>
-            <version>0.2</version>
+            <version>0.21</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.eclipse.jetty</groupId>
@@ -188,12 +198,13 @@
             <version>1.0.0</version>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>com.jayway.restassured</groupId>
-            <artifactId>rest-assured</artifactId>
-            <version>2.4.0</version>
-            <scope>provided</scope>
-        </dependency>
+        <!-- deprecated -->
+        <!--<dependency>-->
+        <!--<groupId>com.jayway.restassured</groupId>-->
+        <!--<artifactId>rest-assured</artifactId>-->
+        <!--<version>2.4.0</version>-->
+        <!--<scope>provided</scope>-->
+        <!--</dependency>-->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
diff --git a/src/main/java/de/ids_mannheim/korap/config/AuditingHandler.java b/src/main/java/de/ids_mannheim/korap/config/AuditingHandler.java
deleted file mode 100644
index 30d08f1..0000000
--- a/src/main/java/de/ids_mannheim/korap/config/AuditingHandler.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @author hanl
- * @date 17/06/2015
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface AuditingHandler {
-}
diff --git a/src/main/java/de/ids_mannheim/korap/config/AuthenticationHandler.java b/src/main/java/de/ids_mannheim/korap/config/AuthenticationHandler.java
deleted file mode 100644
index d712490..0000000
--- a/src/main/java/de/ids_mannheim/korap/config/AuthenticationHandler.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-/**
- * @author hanl
- * @date 17/06/2015
- */
-public @interface AuthenticationHandler {
-}
diff --git a/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java b/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
index 11b8b60..4f255e1 100644
--- a/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
+++ b/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
@@ -1,10 +1,15 @@
 package de.ids_mannheim.korap.config;
 
-import de.ids_mannheim.korap.interfaces.AuditingIface;
+import de.ids_mannheim.korap.interfaces.*;
+import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 import org.springframework.context.support.FileSystemXmlApplicationContext;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * User: hanl
  * Date: 10/9/13
@@ -13,43 +18,117 @@
 public class BeanConfiguration {
 
     private static final String config_file = "default-config.xml";
+    public static final String KUSTVAKT_DB = "kustvakt_db";
 
-    private static ApplicationContext context = null;
+    public static final String KUSTVAKT_ENCRYPTION = "kustvakt_encryption";
+    public static final String KUSTVAKT_AUDITING = "kustvakt_auditing";
+    public static final String KUSTVAKT_CONFIG = "kustvakt_config";
+
+    private static BeanHolder beans;
+
+    public static void setCustomBeansHolder(BeanHolder holder) {
+        ApplicationContext context = beans.context;
+        holder.context = context;
+        BeanConfiguration.beans = holder;
+    }
+
+    public static BeanHolder getBeans() {
+        return BeanConfiguration.beans;
+    }
+
+    public static void loadAuthenticationProviders() {
+        Set<Class<? extends AuthenticationIface>> set = KustvaktClassLoader
+                .loadSubTypes(AuthenticationIface.class);
+        Set<AuthenticationIface> set2 = new HashSet<>();
+        for (Class<? extends AuthenticationIface> i : set) {
+            try {
+                set2.add(i.newInstance());
+            }catch (InstantiationException | IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            getBeans().getAuthenticationManager().setProviders(set2);
+        }catch (RuntimeException e) {
+            // do nothing
+        }
+    }
 
     public static void loadClasspathContext(String... files) {
-        if (context == null && files.length == 0)
-            context = new ClassPathXmlApplicationContext(config_file);
-        else if (context == null)
-            context = new ClassPathXmlApplicationContext(files);
+        if (beans == null) {
+            ApplicationContext context;
+            if (files.length == 0)
+                context = new ClassPathXmlApplicationContext(config_file);
+            else
+                context = new ClassPathXmlApplicationContext(files);
+            BeanConfiguration.beans = new BeanHolder(context);
+        }
     }
 
     public static void loadFileContext(String filepath) {
-        if (context == null)
-            context = new FileSystemXmlApplicationContext("file:" + filepath);
+        if (beans == null) {
+            ApplicationContext context = new FileSystemXmlApplicationContext(
+                    "file:" + filepath);
+            BeanConfiguration.beans = new BeanHolder(context);
+        }
+    }
+    //todo: set response handler
+    public static KustvaktResponseHandler getResponseHandler() {
+        return null;
     }
 
-    public static <T extends KustvaktConfiguration> T getConfiguration() {
-        return (T) getBean("config");
-    }
+    public static class BeanHolder {
 
-    public static <T extends KustvaktConfiguration> T getConfiguration(
-            Class<T> clazz) {
-        return getBean(clazz);
-    }
+        private ApplicationContext context = null;
+        private PluginHandler handler;
 
-    public static boolean hasContext() {
-        return context != null;
-    }
+        public BeanHolder() {
+            this.handler = new PluginHandler();
+        }
 
-    protected static <T> T getBean(Class<T> clazz) {
-        return context.getBean(clazz);
-    }
+        private BeanHolder(ApplicationContext context) {
+            this.context = context;
+        }
 
-    protected static <T> T getBean(String name) {
-        return (T) context.getBean(name);
-    }
+        protected <T> T getBean(Class<T> clazz) {
+            try {
+                return context.getBean(clazz);
+            }catch (NoSuchBeanDefinitionException e) {
+                return this.handler.getDefault(clazz);
+            }
+        }
 
-    public static AuditingIface getAuditingProvider() {
-        return (AuditingIface) context.getBean("auditingProvider");
+        protected <T> T getBean(String name) {
+            try {
+                return (T) context.getBean(name);
+            }catch (NoSuchBeanDefinitionException e) {
+                return (T) this.handler.getDefault(name);
+            }
+        }
+
+        public AuditingIface getAuditingProvider() {
+            return (AuditingIface) context.getBean(KUSTVAKT_AUDITING);
+        }
+
+        public <T extends KustvaktConfiguration> T getConfiguration() {
+            return (T) getBean(KUSTVAKT_CONFIG);
+        }
+
+        public PersistenceClient getPersistenceClient() {
+            return getBean(KUSTVAKT_DB);
+        }
+
+        public AuthenticationManagerIface getAuthenticationManager() {
+            throw new RuntimeException("!Stub");
+        }
+
+        public EntityHandlerIface getUserDBHandler() {
+            throw new RuntimeException("!Stub");
+        }
+
+        public EncryptionIface getEncryption() {
+            return getBean(KUSTVAKT_ENCRYPTION);
+        }
+
     }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/config/Configurable.java b/src/main/java/de/ids_mannheim/korap/config/Configurable.java
new file mode 100644
index 0000000..af656a2
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/config/Configurable.java
@@ -0,0 +1,13 @@
+package de.ids_mannheim.korap.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * @author hanl
+ * @date 27/07/2015
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Configurable {
+    String value();
+}
diff --git a/src/main/java/de/ids_mannheim/korap/config/EncryptionHandler.java b/src/main/java/de/ids_mannheim/korap/config/EncryptionHandler.java
deleted file mode 100644
index b0a28ac..0000000
--- a/src/main/java/de/ids_mannheim/korap/config/EncryptionHandler.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-/**
- * @author hanl
- * @date 18/06/2015
- */
-public @interface EncryptionHandler {
-}
diff --git a/src/main/java/de/ids_mannheim/korap/config/KustvaktClassLoader.java b/src/main/java/de/ids_mannheim/korap/config/KustvaktClassLoader.java
index 4cc7f12..ed3b832 100644
--- a/src/main/java/de/ids_mannheim/korap/config/KustvaktClassLoader.java
+++ b/src/main/java/de/ids_mannheim/korap/config/KustvaktClassLoader.java
@@ -14,6 +14,10 @@
     private static final Reflections reflections = new Reflections(
             "de.ids_mannheim.korap");
 
+
+    private KustvaktClassLoader() {
+
+    }
     /**
      * loads interface implementations in current classpath
      *
@@ -21,7 +25,7 @@
      * @param <T>
      * @return
      */
-    public static <T> Set<Class<? extends T>> load(Class<T> iface) {
+    public static <T> Set<Class<? extends T>> loadSubTypes(Class<T> iface) {
         return reflections.getSubTypesOf(iface);
     }
 
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 bac1486..49eb4df 100644
--- a/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
+++ b/src/main/java/de/ids_mannheim/korap/config/KustvaktConfiguration.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.config;
 
-import de.ids_mannheim.korap.utils.KorAPLogger;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
 import lombok.Getter;
 import org.apache.log4j.PropertyConfigurator;
 import org.slf4j.Logger;
@@ -14,7 +14,7 @@
 import java.util.Properties;
 
 /**
- * if configuration class is extended, load method should be overriden
+ * if configuration class is extended, loadSubTypes method should be overriden
  *
  * @author hanl
  * @date 05/02/2014
@@ -23,7 +23,7 @@
 @Getter
 public class KustvaktConfiguration {
 
-    private final Logger jlog = KorAPLogger
+    private final Logger jlog = KustvaktLogger
             .initiate(KustvaktConfiguration.class);
     private String indexDir;
     private int port;
@@ -115,7 +115,7 @@
     }
 
     private void loadLog4jLogger(String log4jconfig) {
-        /** load log4j configuration file programmatically */
+        /** loadSubTypes log4j configuration file programmatically */
         Properties log4j = new Properties();
         try {
             if (!log4jconfig.equals("")) {
diff --git a/src/main/java/de/ids_mannheim/korap/config/PluginHandler.java b/src/main/java/de/ids_mannheim/korap/config/PluginHandler.java
index 2944aa1..47ddf59 100644
--- a/src/main/java/de/ids_mannheim/korap/config/PluginHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/config/PluginHandler.java
@@ -1,13 +1,6 @@
 package de.ids_mannheim.korap.config;
 
-import de.ids_mannheim.korap.interfaces.AuditingIface;
-import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
-import de.ids_mannheim.korap.interfaces.EncryptionIface;
-import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
-
-import java.lang.annotation.Annotation;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -17,62 +10,45 @@
  */
 public class PluginHandler {
 
-    private static Map<Class<? extends Annotation>, Class> interfaces;
-    private Map<Class<? extends Annotation>, Object> plugins;
-
-    // add resource handler annotation
-    static {
-        interfaces = new HashMap<>();
-        interfaces.put(AuditingHandler.class, AuditingIface.class);
-        interfaces.put(UserDbHandler.class, EntityHandlerIface.class);
-        interfaces.put(AuthenticationHandler.class,
-                AuthenticationManagerIface.class);
-        interfaces.put(EncryptionHandler.class, EncryptionIface.class);
-        //todo:
-        interfaces.put(ResourceHandler.class, ResourceHandler.class);
-    }
+    private Map<String, Object> defaults;
 
     public PluginHandler() {
-        this.plugins = new HashMap<>();
-        this.load();
+        this.defaults = new HashMap<>();
+        loadClasses();
     }
 
-    public void load() {
-        for (Map.Entry<Class<? extends Annotation>, Class> en : new HashSet<>(
-                interfaces.entrySet())) {
-            Set<Class<?>> set = KustvaktClassLoader
-                    .loadFromAnnotation(en.getKey());
-            if (set.size() > 1)
-                throw new UnsupportedOperationException(
-                        "handler declaration not unique!");
-            else if (set.size() == 0)
-                interfaces.remove(en.getKey());
+    private void loadClasses() {
+        Set<Class<?>> cls = KustvaktClassLoader
+                .loadFromAnnotation(Configurable.class);
+        for (Class clazz : cls) {
+            Configurable c = (Configurable) clazz
+                    .getAnnotation(Configurable.class);
+            try {
+                this.defaults.put(c.value(), clazz.newInstance());
+            }catch (InstantiationException | IllegalAccessException e) {
+                throw new RuntimeException("Could not instantiate class");
+            }
         }
     }
 
-    public void addInterface(Class<? extends Annotation> anno, Class<?> iface) {
-        interfaces.put(anno, iface);
+    public Object getDefault(String name) {
+        return this.defaults.get(name);
     }
 
-    public void registerPlugin(Object ob) {
-        for (Map.Entry<Class<? extends Annotation>, Class> en : interfaces
-                .entrySet()) {
-            if (en.getValue().isInstance(ob))
-                this.plugins.put(en.getKey(), ob);
+    public <T> T getDefault(Class<T> tClass) {
+        for (Object o : this.defaults.values()) {
+            if (o.getClass().equals(tClass))
+                return (T) o;
         }
+        return null;
     }
 
-    public Object getPluginInstance(Class<? extends Annotation> anno) {
-        Object o = this.plugins.get(anno);
-        if (o == null)
-            return new NullPointerException(
-                    "no plugin defined for type " + anno.toString());
-        return o;
+    public void remove(String name) {
+        this.defaults.remove(name);
     }
 
     @Override
     public String toString() {
-        System.out.println("PRINT INTERFACES " + interfaces.toString());
-        return plugins.toString();
+        return defaults.toString();
     }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/config/ProtectedResource.java b/src/main/java/de/ids_mannheim/korap/config/ProtectedResource.java
deleted file mode 100644
index 2d24c8b..0000000
--- a/src/main/java/de/ids_mannheim/korap/config/ProtectedResource.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-/**
- * @author hanl
- * @date 18/06/2015
- */
-public @interface ProtectedResource {
-}
diff --git a/src/main/java/de/ids_mannheim/korap/config/ResourceHandler.java b/src/main/java/de/ids_mannheim/korap/config/ResourceHandler.java
deleted file mode 100644
index aae143f..0000000
--- a/src/main/java/de/ids_mannheim/korap/config/ResourceHandler.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-/**
- * @author hanl
- * @date 18/06/2015
- */
-public @interface ResourceHandler {
-}
diff --git a/src/main/java/de/ids_mannheim/korap/config/UserDbHandler.java b/src/main/java/de/ids_mannheim/korap/config/UserDbHandler.java
deleted file mode 100644
index 304f16c..0000000
--- a/src/main/java/de/ids_mannheim/korap/config/UserDbHandler.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.ids_mannheim.korap.config;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @author hanl
- * @date 17/06/2015
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface UserDbHandler {
-}
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/AuditingIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/AuditingIface.java
index 873f435..410ecbd 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/AuditingIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/AuditingIface.java
@@ -2,6 +2,7 @@
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
 import de.ids_mannheim.korap.user.User;
+import edu.emory.mathcs.backport.java.util.Collections;
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 
@@ -14,10 +15,11 @@
  * Time: 10:45 AM
  */
 //fixme: move table to different database!
-public abstract class AuditingIface implements Runnable {
+public abstract class AuditingIface {
 
     protected static int BATCH_SIZE = 15;
-    private final List<AuditRecord> records = new ArrayList<>(BATCH_SIZE + 5);
+    private final List<AuditRecord> records = Collections
+            .synchronizedList(new ArrayList<>(BATCH_SIZE + 5));
     private final List<AuditRecord> buffer = new ArrayList<>(BATCH_SIZE + 5);
 
     public abstract <T extends AuditRecord> List<T> retrieveRecords(
@@ -37,7 +39,12 @@
         if (buffer.size() > BATCH_SIZE) {
             records.clear();
             records.addAll(buffer);
-            run();
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    apply();
+                }
+            }).start();
             buffer.clear();
         }
         if (buffer.size() <= BATCH_SIZE)
@@ -53,6 +60,8 @@
             addAndRun(rec);
     }
 
+    public abstract void apply();
+
     protected List<AuditRecord> getRecordsToSave() {
         return this.records;
     }
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
index 4021836..f44bdab 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/AuthenticationManagerIface.java
@@ -1,11 +1,9 @@
 package de.ids_mannheim.korap.interfaces;
 
-import de.ids_mannheim.korap.config.KustvaktClassLoader;
 import de.ids_mannheim.korap.exceptions.KorAPException;
 import de.ids_mannheim.korap.user.*;
 
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -19,21 +17,6 @@
 
     public AuthenticationManagerIface() {
         this.providers = new HashMap<>();
-        loadProviders();
-    }
-
-    private void loadProviders() {
-        Set<Class<? extends AuthenticationIface>> set = KustvaktClassLoader
-                .load(AuthenticationIface.class);
-        Set<AuthenticationIface> set2 = new HashSet<>();
-        for (Class<? extends AuthenticationIface> i : set) {
-            try {
-                set2.add(i.newInstance());
-            }catch (InstantiationException | IllegalAccessException e) {
-                e.printStackTrace();
-            }
-        }
-        this.setProviders(set2);
     }
 
     public void setProviders(Set<AuthenticationIface> providers) {
@@ -88,6 +71,9 @@
     public abstract Object[] validateResetPasswordRequest(String username,
             String email) throws KorAPException;
 
+    public abstract void resetPassword(String uriFragment, String username,
+            String newPassphrase) throws KorAPException;
+
     public abstract void confirmRegistration(String uriFragment,
             String username) throws KorAPException;
 }
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/PersistenceClient.java b/src/main/java/de/ids_mannheim/korap/interfaces/PersistenceClient.java
new file mode 100644
index 0000000..43e0faa
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/PersistenceClient.java
@@ -0,0 +1,52 @@
+package de.ids_mannheim.korap.interfaces;
+
+import lombok.Getter;
+
+import java.io.*;
+
+@Getter
+public abstract class PersistenceClient<SOURCE> {
+
+    private SOURCE source;
+    private TYPE type;
+    protected String database;
+    private InputStream schema;
+
+    public PersistenceClient(String database, TYPE type) {
+        this.type = type;
+        this.database = database;
+    }
+
+    public PersistenceClient(TYPE type) {
+        this.type = type;
+    }
+
+    public PersistenceClient() {
+    }
+
+    protected void setSource(SOURCE conn) {
+        this.source = conn;
+    }
+
+    public void setDatabase(String name) {
+        this.database = name;
+    }
+
+    public void setSchema(String schema_path) throws FileNotFoundException {
+        this.schema = new FileInputStream(new File(schema_path));
+    }
+
+    // for spring configuration
+    @Deprecated
+    public void setSchema(InputStream schema) throws IOException {
+        this.schema = schema;
+    }
+
+    public abstract boolean checkDatabase() throws Exception;
+
+    public abstract void createDatabase() throws IOException;
+
+    public enum TYPE {
+        SQL, CASSANDRA
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultAuditing.java b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultAuditing.java
index 27bb3a1..24bc445 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultAuditing.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultAuditing.java
@@ -1,6 +1,8 @@
 package de.ids_mannheim.korap.interfaces.defaults;
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.Configurable;
 import de.ids_mannheim.korap.interfaces.AuditingIface;
 import de.ids_mannheim.korap.user.User;
 import org.joda.time.DateTime;
@@ -16,6 +18,7 @@
  * @author hanl
  * @date 05/06/2015
  */
+@Configurable(BeanConfiguration.KUSTVAKT_AUDITING)
 public class DefaultAuditing extends AuditingIface {
 
     private FileOutputStream stream;
@@ -56,7 +59,7 @@
     }
 
     @Override
-    public void run() {
+    public void apply() {
         try {
             for (AuditRecord r : getRecordsToSave())
                 stream.write((r.toString() + "\n").getBytes());
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultEncryption.java b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultEncryption.java
index 64f3b5e..a79c82f 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultEncryption.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/DefaultEncryption.java
@@ -1,5 +1,7 @@
 package de.ids_mannheim.korap.interfaces.defaults;
 
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.Configurable;
 import de.ids_mannheim.korap.exceptions.KorAPException;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.user.User;
@@ -14,7 +16,7 @@
  * @author hanl
  * @date 05/06/2015
  */
-//todo: init!
+@Configurable(BeanConfiguration.KUSTVAKT_ENCRYPTION)
 public class DefaultEncryption implements EncryptionIface {
 
     private SecureRandom randomizer;
diff --git a/src/main/java/de/ids_mannheim/korap/resource/LayerMapper.java b/src/main/java/de/ids_mannheim/korap/resource/LayerMapper.java
index f5f339d..28725ac 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/LayerMapper.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/LayerMapper.java
@@ -1,6 +1,5 @@
 package de.ids_mannheim.korap.resource;
 
-import de.ids_mannheim.korap.config.BeanConfiguration;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.user.UserSettings;
 
@@ -13,13 +12,13 @@
     private UserSettings settings;
     private KustvaktConfiguration config;
 
-    public LayerMapper(UserSettings settings) {
+    public LayerMapper(KustvaktConfiguration config, UserSettings settings) {
         this.settings = settings;
-        this.config = BeanConfiguration.getConfiguration();
+        this.config = config;
     }
 
-    public LayerMapper() {
-        this.config = BeanConfiguration.getConfiguration();
+    public LayerMapper(KustvaktConfiguration config) {
+        this.config = config;
     }
 
     /**
diff --git a/src/main/java/de/ids_mannheim/korap/resource/LayerProcessor.java b/src/main/java/de/ids_mannheim/korap/resource/LayerProcessor.java
index 90b6319..952e308 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/LayerProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/LayerProcessor.java
@@ -2,6 +2,7 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
 
 import java.util.Iterator;
 
@@ -13,8 +14,8 @@
 
     private LayerMapper mapper;
 
-    public LayerProcessor() {
-        this.mapper = new LayerMapper();
+    public LayerProcessor(KustvaktConfiguration config) {
+        this.mapper = new LayerMapper(config);
     }
 
     @Override
diff --git a/src/main/java/de/ids_mannheim/korap/resource/RewriteProcessor.java b/src/main/java/de/ids_mannheim/korap/resource/RewriteProcessor.java
index 6031261..4d2a2a4 100644
--- a/src/main/java/de/ids_mannheim/korap/resource/RewriteProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/resource/RewriteProcessor.java
@@ -1,7 +1,6 @@
 package de.ids_mannheim.korap.resource;
 
 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.utils.JsonUtils;
 
@@ -17,10 +16,10 @@
     private KustvaktConfiguration config;
     private List<NodeProcessor> processors;
 
-    public RewriteProcessor() {
-        this.config = BeanConfiguration.getConfiguration();
+    public RewriteProcessor(KustvaktConfiguration config) {
+        this.config = config;
         this.processors = new ArrayList<>();
-        addProcessor(new LayerProcessor());
+        addProcessor(new LayerProcessor(config));
     }
 
     public JsonNode process(JsonNode node) {
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
new file mode 100644
index 0000000..93db8ae
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionCleanupFilter.java
@@ -0,0 +1,79 @@
+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.utils.JsonUtils;
+
+import java.util.Iterator;
+
+/**
+ * @author hanl
+ * @date 28/07/2015
+ */
+//todo: test
+public class CollectionCleanupFilter extends RewriteQuery {
+
+    // track path to operand
+    private StringBuilder builder;
+
+    public CollectionCleanupFilter() {
+        this.builder = new StringBuilder();
+    }
+
+    @Override
+    public JsonNode rewrite(KoralNode node) {
+        if (node.rawNode().has("collection")) {
+            JsonNode coll = node.rawNode().path("collection");
+            process(coll);
+        }
+        return null;
+    }
+
+    private JsonNode process(JsonNode root) {
+        if (root.isObject()) {
+            if (root.has("operands")) {
+                JsonNode node = root.at("/operands");
+                Iterator<JsonNode> it = node.elements();
+                while (it.hasNext()) {
+                    JsonNode n = it.next();
+                    JsonNode s = process(n);
+                    if (s == null)
+                        it.remove();
+                }
+            }
+
+            JsonNode sub = processNodes(root);
+            if (!root.equals(sub)) {
+                if (sub == null) {
+                    //can't do anything here -- fixme: edge case?!
+                    return null;
+                }else if (sub.isObject()) {
+                    ObjectNode ob = (ObjectNode) root;
+                    ob.removeAll();
+                    ob.putAll((ObjectNode) sub);
+                }
+
+            }
+        }
+        return root;
+    }
+
+    // return null deletes node, if node return replace at level -1
+    private JsonNode processNodes(JsonNode jsonNode) {
+        if (jsonNode.isObject()) {
+            if (jsonNode.has("operands")) {
+                JsonNode node = jsonNode.at("/operands");
+                int count = node.size();
+                if (count == 1) {
+                    // move to super node if any
+                    return node.path(0);
+                }else if (count == 0) {
+                    // remove container
+                    return null;
+                }
+                return jsonNode;
+            }
+        }
+        return JsonUtils.createArrayNode();
+    }
+}
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
new file mode 100644
index 0000000..a4cf771
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/CollectionConstraint.java
@@ -0,0 +1,29 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.user.User;
+
+/**
+ * @author hanl
+ * @date 03/07/2015
+ */
+public class CollectionConstraint extends RewriteNode {
+
+    @Override
+    public JsonNode rewrite(KoralNode koralnode) {
+        JsonNode node = koralnode.rawNode();
+        if (node.at("/@type").asText().equals("koral:doc")) {
+            if (node.at("/key").asText().equals("corpusID") && !check(node,
+                    koralnode.getUser())) {
+                koralnode.removeNode();
+                // todo: add message that node was removed!
+            }
+        }
+        return node;
+    }
+
+    private boolean check(JsonNode node, User user) {
+        return false;
+    }
+
+}
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
new file mode 100644
index 0000000..58e3ff2
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/FoundryInject.java
@@ -0,0 +1,39 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.resource.LayerMapper;
+
+/**
+ * @author hanl
+ * @date 30/06/2015
+ */
+public class FoundryInject extends RewriteNode {
+
+    private KustvaktConfiguration config;
+
+    public FoundryInject(KustvaktConfiguration config) {
+        this.config = config;
+    }
+
+    @Override
+    public JsonNode rewrite(KoralNode node) {
+        LayerMapper mapper;
+        if (node.hasUser())
+            mapper = new LayerMapper(config, node.getUser().getSettings());
+        else
+            mapper = new LayerMapper(config);
+
+        if (node.rawNode().path("@type").asText().equals("koral:term") && !node
+                .rawNode().has("foundry")) {
+            String layer;
+            if (node.rawNode().has("layer"))
+                layer = node.rawNode().path("layer").asText();
+            else
+                layer = node.rawNode().path("key").asText();
+            String foundry = mapper.findFoundry(layer);
+            node.set("foundry", foundry);
+        }
+        return node.rawNode();
+    }
+}
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
new file mode 100644
index 0000000..e708504
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/KoralNode.java
@@ -0,0 +1,145 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 04/07/2015
+ */
+public abstract class KoralNode {
+    private JsonNode node;
+    private KoralRewriteBuilder builder;
+    private boolean toRemove;
+    private final User user;
+
+    private KoralNode(JsonNode node) {
+        this(node, null);
+    }
+
+    public KoralNode(JsonNode node, User user) {
+        this.node = node;
+        this.builder = new KoralRewriteBuilder();
+        this.toRemove = false;
+        this.user = user;
+    }
+
+    public boolean hasUser() {
+        return this.user != null;
+    }
+
+    public User getUser() {
+        return this.user;
+    }
+
+    public static KoralNode getNode(JsonNode node) {
+        return new KoralNode(node) {
+        };
+    }
+
+    public void set(String name, Object value) {
+
+        if (this.node.isObject()) {
+            ObjectNode node = (ObjectNode) this.node;
+            if (value instanceof String)
+                node.put(name, (String) value);
+            else if (value instanceof Integer)
+                node.put(name, (Integer) value);
+            builder.setOperation("injection");
+            builder.build(this.node);
+        }else
+            throw new UnsupportedOperationException(
+                    "node doesn't support this operation");
+    }
+
+    public void remove(Object identifier) {
+        boolean set = false;
+        if (this.node.isObject() && identifier instanceof String) {
+            ObjectNode n = (ObjectNode) this.node;
+            n.remove((String) identifier);
+            set = true;
+        }else if (this.node.isArray() && identifier instanceof Integer) {
+            ArrayNode n = (ArrayNode) this.node;
+            n.remove((Integer) identifier);
+            set = true;
+        }
+        if (set) {
+            builder.setOperation("deletion");
+            builder.build(this.node);
+        }
+    }
+
+    public void replace(String name, String value) {
+        if (this.node.isObject() && this.node.has(name)) {
+            ObjectNode n = (ObjectNode) this.node;
+            n.put(name, value);
+            builder.setOperation("override");
+            builder.build(this.node);
+        }
+    }
+
+    public JsonNode rawNode() {
+        return this.node;
+    }
+
+    public void removeNode() {
+        this.toRemove = true;
+    }
+
+    public boolean toRemove() {
+        return this.toRemove;
+    }
+
+    private static class KoralRewriteBuilder {
+
+        private Map<String, String> map;
+
+        public KoralRewriteBuilder() {
+            this.map = new LinkedHashMap<>();
+            this.map.put("@type", "koral:rewrite");
+            this.map.put("src", "Kustvakt");
+        }
+
+        public KoralRewriteBuilder setOperation(String op) {
+            if (!op.startsWith("operation:"))
+                op = "operation:" + op;
+            this.map.put("operation", op);
+            return this;
+        }
+
+        public KoralRewriteBuilder setScope(String scope) {
+            this.map.put("scope", scope);
+            return this;
+        }
+
+        public JsonNode build(JsonNode node) {
+            if (this.map.get("operation") == null)
+                throw new UnsupportedOperationException(
+                        "operation not set properly");
+
+            if (node.has("rewrites")) {
+                ArrayNode n = (ArrayNode) node.path("rewrites");
+                n.add(JsonUtils.valueToTree(this.map));
+            }else {
+                ObjectNode n = (ObjectNode) node;
+                List l = new LinkedList<>();
+                l.add(JsonUtils.valueToTree(this.map));
+                n.put("rewrites", JsonUtils.valueToTree(l));
+            }
+            return node;
+        }
+
+    }
+}
+
+
+
+
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
new file mode 100644
index 0000000..5676817
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteHandler.java
@@ -0,0 +1,87 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+
+/**
+ * @author hanl
+ * @date 30/06/2015
+ */
+//todo: load rewritenode and rewritequery automatically from classpath, but namespaced from package
+public class RewriteHandler {
+
+    private static Logger jlog = KustvaktLogger.initiate(RewriteHandler.class);
+    private Collection<RewriteNode> node_processors;
+    private Collection<RewriteQuery> query_processors;
+
+    public RewriteHandler() {
+        this.node_processors = new HashSet<>();
+        this.query_processors = new HashSet<>();
+        // add defaults?!
+    }
+
+    public void add(RewriteNode node) {
+        this.node_processors.add(node);
+    }
+
+    public void add(RewriteQuery node) {
+        this.query_processors.add(node);
+    }
+
+    public void clear() {
+        this.node_processors.clear();
+        this.query_processors.clear();
+    }
+
+    private boolean process(JsonNode root, User user) {
+        if (root.isObject()) {
+            if (root.has("operands")) {
+                JsonNode node = root.at("/operands");
+                Iterator<JsonNode> it = node.elements();
+                while (it.hasNext()) {
+                    JsonNode n = it.next();
+                    if (!process(n, user))
+                        it.remove();
+                }
+            }else if (root.has("wrap")) {
+                JsonNode node = root.at("/wrap");
+                //todo: remove object nodes as well
+                process(node, user);
+            }else
+                return processNode(root, user, this.node_processors);
+        }
+        return true;
+    }
+
+    public JsonNode apply(JsonNode root, User user) {
+        for (JsonNode n : root)
+            process(n, user);
+        processNode(root, user, this.query_processors);
+        return root;
+    }
+
+    public String apply(String json, User user) {
+        return JsonUtils.toJSON(apply(JsonUtils.readTree(json), user));
+    }
+
+    private static boolean processNode(JsonNode node, User user,
+            Collection<? extends RewriteTask> tasks) {
+        KoralNode knode = KoralNode.getNode(node);
+        for (RewriteTask task : tasks) {
+            jlog.debug("running node in processor " + node);
+            jlog.debug("on processor " + task.getClass().toString());
+            task.rewrite(knode);
+            if (knode.toRemove())
+                break;
+        }
+        return !knode.toRemove();
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteNode.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteNode.java
new file mode 100644
index 0000000..cb0a06c
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteNode.java
@@ -0,0 +1,20 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+/**
+ * node rewrites get injected typically object nodes that are subject to altering.
+ * Be aware that node rewrites are processed before query rewrites. Thus query rewrite may override previous node rewrites
+ *
+ * {@link de.ids_mannheim.korap.resource.rewrite.RewriteNode} rewrite support the deletion of the respective node by simply setting the node invalid in KoralNode
+ *
+ * @author hanl
+ * @date 03/07/2015
+ */
+public abstract class RewriteNode extends RewriteTask {
+
+    public RewriteNode() {
+        super();
+    }
+
+
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteQuery.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteQuery.java
new file mode 100644
index 0000000..99bfb34
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteQuery.java
@@ -0,0 +1,18 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+/**
+ * query rewrites get injected the entire query from root containing all child nodes
+ * <p/>
+ * {@link de.ids_mannheim.korap.resource.rewrite.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
+ *
+ * @author hanl
+ * @date 03/07/2015
+ */
+public abstract class RewriteQuery extends RewriteTask {
+
+    public RewriteQuery() {
+        super();
+    }
+
+}
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
new file mode 100644
index 0000000..ed5ad34
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteTask.java
@@ -0,0 +1,17 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import lombok.Getter;
+
+/**
+ * @author hanl
+ * @date 30/06/2015
+ */
+@Getter
+public abstract class RewriteTask {
+
+    protected RewriteTask() {
+    }
+
+    public abstract JsonNode rewrite(KoralNode node);
+}
diff --git a/src/main/java/de/ids_mannheim/korap/user/Attributes.java b/src/main/java/de/ids_mannheim/korap/user/Attributes.java
index 0bba5b7..13303e6 100644
--- a/src/main/java/de/ids_mannheim/korap/user/Attributes.java
+++ b/src/main/java/de/ids_mannheim/korap/user/Attributes.java
@@ -27,6 +27,7 @@
 
     public static final String TYPE = "type";
 
+    public static final String ID = "ID";
     public static final String UID = "accountID";
     public static final String USERNAME = "username";
     public static final String PASSWORD = "password";
diff --git a/src/main/java/de/ids_mannheim/korap/user/KorAPUser.java b/src/main/java/de/ids_mannheim/korap/user/KorAPUser.java
index 5eb6932..ab1c164 100644
--- a/src/main/java/de/ids_mannheim/korap/user/KorAPUser.java
+++ b/src/main/java/de/ids_mannheim/korap/user/KorAPUser.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.user;
 
-import de.ids_mannheim.korap.utils.KorAPLogger;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
 import lombok.Getter;
 import lombok.Setter;
 import org.slf4j.Logger;
@@ -8,7 +8,7 @@
 @Getter
 @Setter
 public class KorAPUser extends User {
-    private static Logger jlog = KorAPLogger.initiate(KorAPUser.class);
+    private static Logger jlog = KustvaktLogger.initiate(KorAPUser.class);
     private static final long serialVersionUID = -7108308497625884584L;
 
     //fixme: accountlink to shibboleth account
diff --git a/src/main/java/de/ids_mannheim/korap/user/User.java b/src/main/java/de/ids_mannheim/korap/user/User.java
index 2b28edd..32af973 100644
--- a/src/main/java/de/ids_mannheim/korap/user/User.java
+++ b/src/main/java/de/ids_mannheim/korap/user/User.java
@@ -1,6 +1,7 @@
 package de.ids_mannheim.korap.user;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.config.ParamFields;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import lombok.Data;
@@ -23,7 +24,7 @@
     private Long accountCreation;
     private boolean isAccountLocked;
     private int type;
-    private Map<String, Object> fields;
+    private ParamFields fields;
     private UserSettings settings;
     private UserDetails details;
     private List<UserQuery> queries;
@@ -32,7 +33,6 @@
         this.accountCreation = TimeUtils.getNow().getMillis();
         this.isAccountLocked = false;
         this.username = "";
-        this.fields = new HashMap<>();
         this.id = -1;
     }
 
@@ -46,12 +46,12 @@
         this.username = username;
     }
 
-    public void setField(String key, Object value) {
-        this.fields.put(key, value);
+    public void addField(ParamFields.Param param) {
+        this.fields.add(param);
     }
 
-    public Object getField(String key) {
-        return this.fields.get(key);
+    public <T extends ParamFields.Param> T getField(Class<T> cl) {
+        return this.fields.get(cl);
     }
 
     //todo: repair transfer
diff --git a/src/main/java/de/ids_mannheim/korap/user/UserSettings.java b/src/main/java/de/ids_mannheim/korap/user/UserSettings.java
index 365e69a..ebb85ed 100644
--- a/src/main/java/de/ids_mannheim/korap/user/UserSettings.java
+++ b/src/main/java/de/ids_mannheim/korap/user/UserSettings.java
@@ -279,7 +279,7 @@
                 (String) m.get(Attributes.DEFAULT_REL_FOUNDRY));
     }
 
-    //load from configuration?
+    //loadSubTypes from configuration?
     private void setupDefaultSettings() {
         this.setFileNameForExport("export");
         //        this.setItemForSimpleAnnotation(0);
diff --git a/src/main/java/de/ids_mannheim/korap/utils/CollectionQueryBuilder3.java b/src/main/java/de/ids_mannheim/korap/utils/CollectionQueryBuilder3.java
index 1b52306..da6f630 100644
--- a/src/main/java/de/ids_mannheim/korap/utils/CollectionQueryBuilder3.java
+++ b/src/main/java/de/ids_mannheim/korap/utils/CollectionQueryBuilder3.java
@@ -9,11 +9,12 @@
 import java.util.Map;
 
 /**
- * convenience builder class for collection query -- new one
+ * convenience builder class for collection query
  *
  * @author hanl
  * @date 16/09/2014
  */
+@Deprecated
 public class CollectionQueryBuilder3 {
 
     private boolean verbose;
diff --git a/src/main/java/de/ids_mannheim/korap/utils/KorAPLogger.java b/src/main/java/de/ids_mannheim/korap/utils/KustvaktLogger.java
similarity index 93%
rename from src/main/java/de/ids_mannheim/korap/utils/KorAPLogger.java
rename to src/main/java/de/ids_mannheim/korap/utils/KustvaktLogger.java
index 5fc876f..90f3c23 100644
--- a/src/main/java/de/ids_mannheim/korap/utils/KorAPLogger.java
+++ b/src/main/java/de/ids_mannheim/korap/utils/KustvaktLogger.java
@@ -9,7 +9,7 @@
  * @date 28/03/2014
  */
 
-public class KorAPLogger implements Logger {
+public class KustvaktLogger implements Logger {
     // debugging flag, info, warn, error will always be logged though!
     public static boolean DEBUG = false;
 
@@ -17,28 +17,29 @@
     public static final String SECURITY_LOG = "securityLog";
 
     //fixme:
-    public static final KorAPLogger ERROR_LOGGER = KorAPLogger
+    public static final KustvaktLogger ERROR_LOGGER = KustvaktLogger
             .initiate(ERROR_LOG);
-    public static final KorAPLogger QUERY_LOGGER = KorAPLogger.initiate("ql");
+    public static final KustvaktLogger QUERY_LOGGER = KustvaktLogger
+            .initiate("ql");
 
     @Deprecated
-    public static final KorAPLogger SECURITY_LOGGER = KorAPLogger
+    public static final KustvaktLogger SECURITY_LOGGER = KustvaktLogger
             .initiate("security");
     private Logger log;
 
-    public static KorAPLogger initiate(Class cl) {
-        KorAPLogger l = new KorAPLogger();
+    public static KustvaktLogger initiate(Class cl) {
+        KustvaktLogger l = new KustvaktLogger();
         l.log = LoggerFactory.getLogger(cl);
         return l;
     }
 
-    public static KorAPLogger initiate(String name) {
-        KorAPLogger l = new KorAPLogger();
+    public static KustvaktLogger initiate(String name) {
+        KustvaktLogger l = new KustvaktLogger();
         l.log = LoggerFactory.getLogger(name);
         return l;
     }
 
-    private KorAPLogger() {
+    private KustvaktLogger() {
     }
 
     @Override
diff --git a/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java b/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java
index a7120aa..ac2c1a7 100644
--- a/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java
+++ b/src/main/java/de/ids_mannheim/korap/utils/StringUtils.java
@@ -1,12 +1,13 @@
 package de.ids_mannheim.korap.utils;
 
-import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang.StringEscapeUtils;
 import org.slf4j.Logger;
 
 import java.util.*;
 
 public class StringUtils {
-    private final static Logger jlog = KorAPLogger.initiate(StringUtils.class);
+    private final static Logger jlog = KustvaktLogger
+            .initiate(StringUtils.class);
 
     private static final String SLASH = "/";
     private static final String SEP = ";";
@@ -153,11 +154,11 @@
     }
 
     public static String normalizeHTML(String value) {
-        return StringEscapeUtils.escapeHtml4(value);
+        return StringEscapeUtils.escapeHtml(value);
     }
 
     public static String decodeHTML(String value) {
-        return StringEscapeUtils.unescapeHtml4(value);
+        return StringEscapeUtils.unescapeHtml(value);
     }
 
     /**
diff --git a/src/main/java/de/ids_mannheim/korap/utils/TimeUtils.java b/src/main/java/de/ids_mannheim/korap/utils/TimeUtils.java
index b4f1d30..3627a4d 100644
--- a/src/main/java/de/ids_mannheim/korap/utils/TimeUtils.java
+++ b/src/main/java/de/ids_mannheim/korap/utils/TimeUtils.java
@@ -25,7 +25,7 @@
 
     private static DecimalFormat df = new DecimalFormat("#.#############");
     private static final DateTimeZone dtz = DateTimeZone.forID("Europe/Berlin");
-    private static Logger jlog = KorAPLogger.initiate(TimeUtils.class);
+    private static Logger jlog = KustvaktLogger.initiate(TimeUtils.class);
 
     public static int convertTimeToSeconds(String expirationVal) {
         expirationVal = expirationVal.trim();
diff --git a/src/main/java/de/ids_mannheim/korap/web/Kustvakt.java b/src/main/java/de/ids_mannheim/korap/web/Kustvakt.java
index f5c14f4..72e8200 100644
--- a/src/main/java/de/ids_mannheim/korap/web/Kustvakt.java
+++ b/src/main/java/de/ids_mannheim/korap/web/Kustvakt.java
@@ -4,7 +4,7 @@
 import com.sun.grizzly.http.servlet.ServletAdapter;
 import com.sun.jersey.spi.container.servlet.ServletContainer;
 import de.ids_mannheim.korap.config.BeanConfiguration;
-import de.ids_mannheim.korap.utils.KorAPLogger;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -24,7 +24,7 @@
         BeanConfiguration.loadClasspathContext();
 
         if (CONFIG != null) {
-            BeanConfiguration.getConfiguration()
+            BeanConfiguration.getBeans().getConfiguration()
                     .setPropertiesAsStream(new FileInputStream(new File(CONFIG)));
 
         }
@@ -33,7 +33,7 @@
 
     public static void grizzlyServer(int port) throws IOException {
         if (port == -1)
-            port = BeanConfiguration.getConfiguration().getPort();
+            port = BeanConfiguration.getBeans().getConfiguration().getPort();
         System.out.println("Starting grizzly on port " + port + " ...");
         GrizzlyWebServer gws = new GrizzlyWebServer(port);
         ServletAdapter jerseyAdapter = new ServletAdapter();
@@ -51,7 +51,7 @@
         for (int i = 0; i < args.length; i++) {
             switch ((args[i])) {
                 case "--debug":
-                    KorAPLogger.DEBUG = true;
+                    KustvaktLogger.DEBUG = true;
                     break;
                 case "--config":
                     CONFIG = args[i + 1];
diff --git a/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java b/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
index 2cf379a..63605c9 100644
--- a/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
+++ b/src/main/java/de/ids_mannheim/korap/web/SearchKrill.java
@@ -9,7 +9,7 @@
 import de.ids_mannheim.korap.response.Result;
 import de.ids_mannheim.korap.util.QueryException;
 import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.utils.KorAPLogger;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
 import org.apache.lucene.store.MMapDirectory;
 import org.slf4j.Logger;
 
@@ -24,8 +24,8 @@
  * @author Nils Diewald
  */
 public class SearchKrill {
-    private final static Logger qlog = KorAPLogger.initiate("queryLogger");
-    private final static Logger log = KorAPLogger.initiate(SearchKrill.class);
+    private final static Logger qlog = KustvaktLogger.initiate("queryLogger");
+    private final static Logger log = KustvaktLogger.initiate(SearchKrill.class);
     // Temporary
     String indexDir = "/data/prep_corpus/index/";
     String i = "/Users/hanl/Projects/prep_corpus";
@@ -42,13 +42,13 @@
             File f = new File(path);
             log.info("Loading index from " + path);
             if (!f.exists()) {
-                KorAPLogger.ERROR_LOGGER.error("Index not found!");
+                KustvaktLogger.ERROR_LOGGER.error("Index not found!");
                 System.exit(-1);
             }
             this.index = new KrillIndex(new MMapDirectory(new File(path)));
         } catch (IOException e) {
-            KorAPLogger.ERROR_LOGGER
-                    .error("Unable to load index: {}", e.getMessage());
+            KustvaktLogger.ERROR_LOGGER
+                    .error("Unable to loadSubTypes index: {}", e.getMessage());
         }
     }
 
@@ -296,7 +296,7 @@
             // Get term relations as a json string
             return kc.getTermRelationJSON(field);
         } catch (IOException e) {
-            KorAPLogger.ERROR_LOGGER
+            KustvaktLogger.ERROR_LOGGER
                     .error("Unable to retrieve term relations: {}",
                             e.getMessage());
             return "{\"documents\" : -1, \"error\" : \"IO error\" }";
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/LightService.java b/src/main/java/de/ids_mannheim/korap/web/service/LightService.java
index 9ae312b..273205b 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/LightService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/LightService.java
@@ -9,8 +9,7 @@
 import de.ids_mannheim.korap.query.serialize.MetaQueryBuilder;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
 import de.ids_mannheim.korap.resource.RewriteProcessor;
-import de.ids_mannheim.korap.utils.CollectionQueryBuilder;
-import de.ids_mannheim.korap.utils.KorAPLogger;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
 import de.ids_mannheim.korap.web.ClientsHandler;
 import de.ids_mannheim.korap.web.SearchKrill;
 import de.ids_mannheim.korap.web.TRACE;
@@ -18,7 +17,10 @@
 import org.slf4j.Logger;
 
 import javax.ws.rs.*;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -27,23 +29,23 @@
  * @author hanl
  * @date 29/01/2014
  */
-//todd test functions
 @Path("v0.1" + "/")
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 public class LightService {
 
-    private static Logger jlog = KorAPLogger.initiate(LightService.class);
+    private static Logger jlog = KustvaktLogger.initiate(LightService.class);
 
     private SearchKrill searchKrill;
     private ClientsHandler graphDBhandler;
     private RewriteProcessor processor;
+    private KustvaktConfiguration config;
 
     public LightService() {
-        this.searchKrill = new SearchKrill(
-                BeanConfiguration.getConfiguration().getIndexDir());
+        this.config = BeanConfiguration.getBeans().getConfiguration();
+        this.searchKrill = new SearchKrill(config.getIndexDir());
         UriBuilder builder = UriBuilder.fromUri("http://10.0.10.13").port(9997);
         this.graphDBhandler = new ClientsHandler(builder.build());
-        this.processor = new RewriteProcessor();
+        this.processor = new RewriteProcessor(this.config);
     }
 
     @POST
@@ -83,8 +85,8 @@
         meta.setSpanContext(context);
         meta.addEntry("cutOff", cutoff);
         ss.setMeta(meta);
-        //todo: test this
-        ss.setCollection(cq);
+        if (cq != null)
+            ss.setCollection(cq);
         return Response.ok(processor.process(ss.toJSON())).build();
     }
 
@@ -92,30 +94,27 @@
     @Path("search")
     public Response queryRaw(@QueryParam("engine") String engine,
             String jsonld) {
-        KustvaktConfiguration.BACKENDS eng = BeanConfiguration
-                .getConfiguration().chooseBackend(engine);
         jsonld = processor.process(jsonld);
         // todo: should be possible to add the meta part to the query serialization
         jlog.info("Serialized search: {}", jsonld);
 
         // fixme: to use the systemarchitecture pointcut thingis, searchkrill must be injected via
         String result = searchKrill.search(jsonld);
-        KorAPLogger.QUERY_LOGGER.trace("The result set: {}", result);
+        KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
         return Response.ok(result).build();
     }
 
     @GET
     @Path("search")
-    public Response searchbyNameAll(@Context SecurityContext securityContext,
-            @QueryParam("q") String q, @QueryParam("ql") String ql,
-            @QueryParam("v") String v, @QueryParam("context") String ctx,
+    public Response searchbyNameAll(@QueryParam("q") String q,
+            @QueryParam("ql") String ql, @QueryParam("v") String v,
+            @QueryParam("context") String ctx,
             @QueryParam("cutoff") Boolean cutoff,
             @QueryParam("count") Integer pageLength,
             @QueryParam("offset") Integer pageIndex,
             @QueryParam("page") Integer pageInteger,
             @QueryParam("cq") String cq, @QueryParam("engine") String engine) {
-        KustvaktConfiguration.BACKENDS eng = BeanConfiguration
-                .getConfiguration().chooseBackend(engine);
+        KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
 
         String result;
         QuerySerializer serializer = new QuerySerializer().setQuery(q, ql, v);
@@ -147,7 +146,7 @@
             }
         }else
             result = searchKrill.search(query);
-        KorAPLogger.QUERY_LOGGER.trace("The result set: {}", result);
+        KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
         return Response.ok(result).build();
     }
 
@@ -171,32 +170,31 @@
      * @param engine
      * @return
      */
-    //fixme: does not use policyrewrite!
+    //fixme: search in collection /collection/collection-id/search
     @GET
     @Path("/{type}/{id}/search")
-    public Response searchbyName(@QueryParam("q") String query,
+    public Response searchbyName(@PathParam("id") String id,
+            @PathParam("type") String type, @QueryParam("q") String query,
             @QueryParam("ql") String ql, @QueryParam("v") String v,
             @QueryParam("context") String ctx,
             @QueryParam("cutoff") Boolean cutoff,
             @QueryParam("count") Integer pageLength,
             @QueryParam("offset") Integer pageIndex,
-            @QueryParam("page") Integer pageInteger, @PathParam("id") String id,
-            @PathParam("type") String type, @QueryParam("cq") String cq,
-            @QueryParam("raw") Boolean raw,
+            @QueryParam("page") Integer pageInteger,
+            @QueryParam("cq") String cq, @QueryParam("raw") Boolean raw,
             @QueryParam("engine") String engine) {
         // ref is a virtual collection id!
-        KustvaktConfiguration.BACKENDS eng = BeanConfiguration
-                .getConfiguration().chooseBackend(engine);
+        KustvaktConfiguration.BACKENDS eng = this.config.chooseBackend(engine);
+        jlog.info("RA??????????????????????????????????? W" + raw);
         raw = raw == null ? false : raw;
         MetaQueryBuilder meta = QueryBuilderUtil
                 .defaultMetaBuilder(pageIndex, pageInteger, pageLength, ctx,
                         cutoff);
         if (!raw) {
-            QuerySerializer s = new QuerySerializer().setQuery(query, ql, v);
-
             // should only apply to CQL queries
             //                meta.addEntry("itemsPerResource", 1);
-            s.setMeta(meta);
+            QuerySerializer s = new QuerySerializer().setQuery(query, ql, v)
+                    .setMeta(meta);
             query = processor.process(s.toJSON());
         }
         String result;
@@ -218,12 +216,12 @@
                 result = searchKrill.search(query);
 
         }catch (Exception e) {
-            KorAPLogger.ERROR_LOGGER
+            KustvaktLogger.ERROR_LOGGER
                     .error("Exception for serialized query: " + query, e);
             throw KustvaktResponseHandler.throwit(500, e.getMessage(), null);
         }
 
-        KorAPLogger.QUERY_LOGGER.trace("The result set: {}", result);
+        KustvaktLogger.QUERY_LOGGER.trace("The result set: {}", result);
         return Response.ok(result).build();
     }
 
@@ -231,17 +229,17 @@
     @POST
     @Path("stats")
     public Response getStats(String json) {
-        CollectionQueryBuilder builder = new CollectionQueryBuilder();
-        builder.addResource(json);
+        //        CollectionQueryBuilder builder = new CollectionQueryBuilder();
+        //        builder.addResource(json);
 
-        String stats = searchKrill.getStatistics(builder.toCollections());
+        // todo: policy override in extension!
+        String stats = searchKrill.getStatistics(json);
         if (stats.contains("-1"))
             throw KustvaktResponseHandler.throwit(StatusCodes.EMPTY_RESULTS);
 
         return Response.ok(stats).build();
     }
 
-
     @GET
     @Path("/corpus/{id}/{docid}/{rest}/matchInfo")
     public Response getMatchInfo(@PathParam("id") String id,
diff --git a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
index f99a520..7a74506 100644
--- a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
@@ -19,7 +19,7 @@
  */
 public class KustvaktResponseHandler {
 
-    private static AuditingIface auditing = BeanConfiguration
+    private static AuditingIface auditing = BeanConfiguration.getBeans()
             .getAuditingProvider();
 
     private static void register(List<AuditRecord> records) {
diff --git a/src/main/resources/default-config.xml b/src/main/resources/default-config.xml
index f0c380f..12dce87 100644
--- a/src/main/resources/default-config.xml
+++ b/src/main/resources/default-config.xml
@@ -10,16 +10,16 @@
 
     <util:properties id="props" location="classpath:kustvakt.conf"/>
 
-    <bean id="auditingProvider"
+    <bean id="kustvakt_auditing"
           class="de.ids_mannheim.korap.interfaces.defaults.DefaultAuditing">
     </bean>
 
-    <bean id="config"
+    <bean id="kustvakt_config"
           class="de.ids_mannheim.korap.config.KustvaktConfiguration">
         <property name="properties" ref="props"/>
     </bean>
 
-    <bean name="encryption"
+    <bean name="kustvakt_encryption"
           class="de.ids_mannheim.korap.interfaces.defaults.DefaultEncryption">
     </bean>
 </beans>
\ No newline at end of file
diff --git a/src/test/java/ClassLoaderTest.java b/src/test/java/ClassLoaderTest.java
new file mode 100644
index 0000000..4f9e455
--- /dev/null
+++ b/src/test/java/ClassLoaderTest.java
@@ -0,0 +1,41 @@
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.PluginHandler;
+import de.ids_mannheim.korap.interfaces.AuditingIface;
+import de.ids_mannheim.korap.interfaces.defaults.DefaultAuditing;
+import org.junit.Test;
+
+/**
+ * @author hanl
+ * @date 27/07/2015
+ */
+public class ClassLoaderTest {
+
+    @Test
+    public void testBeanConfigurationLoaderThrowsNoException() {
+        BeanConfiguration.loadClasspathContext("classpath-config.xml");
+        assert BeanConfiguration.getBeans() != null;
+    }
+
+    @Test
+    public void testDefaultCreationThrowsNoException() {
+        PluginHandler pl = new PluginHandler();
+        Object o = pl.getDefault(BeanConfiguration.KUSTVAKT_AUDITING);
+        assert o != null;
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testDefaultCreationThrowsException() {
+        BeanConfiguration.loadClasspathContext();
+        BeanConfiguration.getBeans().getAuthenticationManager();
+    }
+
+    @Test
+    public void testDefaultInterfaceMatchThrowsNoException() {
+        BeanConfiguration.loadClasspathContext();
+        AuditingIface iface = BeanConfiguration.getBeans()
+                .getAuditingProvider();
+        assert iface != null;
+        assert iface instanceof DefaultAuditing;
+    }
+
+}
diff --git a/src/test/java/FastJerseyTest.java b/src/test/java/FastJerseyTest.java
new file mode 100644
index 0000000..c51e62c
--- /dev/null
+++ b/src/test/java/FastJerseyTest.java
@@ -0,0 +1,116 @@
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.core.DefaultResourceConfig;
+import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
+import com.sun.jersey.test.framework.AppDescriptor;
+import com.sun.jersey.test.framework.LowLevelAppDescriptor;
+import com.sun.jersey.test.framework.spi.container.TestContainer;
+import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
+import com.sun.jersey.test.framework.spi.container.grizzly.GrizzlyTestContainerFactory;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriBuilder;
+import java.net.URI;
+
+/**
+ * @author hanl
+ * @date 29/07/2015
+ */
+public abstract class FastJerseyTest {
+
+    protected static String API_VERSION = "v0.1";
+
+    private static DefaultResourceConfig resourceConfig = new DefaultResourceConfig();
+
+    private static TestContainerFactory testContainerFactory;
+
+    private static TestContainer testContainer;
+
+    private static Client client;
+
+    public static void addClass(Class<?> resourceClass) {
+        resourceConfig.getClasses().add(resourceClass);
+    }
+
+    public static void addSingleton(Object resourceSingleton) {
+        resourceConfig.getSingletons().add(resourceSingleton);
+    }
+
+    public static <T> void addProviderForContext(Class<T> contextClass,
+            T contextObject) {
+        addSingleton(
+                new SingletonTypeInjectableProvider<Context, T>(contextClass,
+                        contextObject) {
+                });
+    }
+
+    public static void addRequestFilter(Object filter) {
+        resourceConfig.getContainerRequestFilters().add(filter);
+    }
+
+    public static void addResponseFilter(Object filter) {
+        resourceConfig.getContainerResponseFilters().add(filter);
+    }
+
+    public static void setTestContainerFactory(
+            TestContainerFactory newTestContainerFactory) {
+        testContainerFactory = newTestContainerFactory;
+    }
+
+    @BeforeClass
+    public static void cleanStaticVariables() {
+        resourceConfig = new DefaultResourceConfig();
+    }
+
+    public static void initServer() {
+        AppDescriptor ad = new LowLevelAppDescriptor.Builder(resourceConfig)
+                .build();
+        TestContainerFactory tcf = testContainerFactory;
+        if (tcf == null) {
+            tcf = new GrizzlyTestContainerFactory();
+        }
+        testContainer = tcf
+                .create(UriBuilder.fromUri("http://localhost/").port(9998)
+                        .build(), ad);
+        client = testContainer.getClient();
+        if (client == null) {
+            client = Client.create(ad.getClientConfig());
+        }
+    }
+
+    public static void startServer() {
+        if (testContainer != null) {
+            testContainer.start();
+        }
+    }
+
+    @AfterClass
+    public static void stopServer() {
+        testContainer.stop();
+        testContainer = null;
+        client = null;
+    }
+
+    public Client client() {
+        return client;
+    }
+
+    public URI getBaseUri() {
+        return testContainer.getBaseUri();
+    }
+
+    public WebResource resource() {
+        return client.resource(getBaseUri());
+    }
+
+    @Before
+    public void startServerBeforeFirstTestRun() {
+        if (testContainer == null) {
+            initServer();
+            startServer();
+        }
+    }
+}
diff --git a/src/test/java/KustvaktCoreRestTest.java b/src/test/java/KustvaktCoreRestTest.java
new file mode 100644
index 0000000..11a935a
--- /dev/null
+++ b/src/test/java/KustvaktCoreRestTest.java
@@ -0,0 +1,79 @@
+import com.sun.jersey.api.client.ClientResponse;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.query.serialize.CollectionQueryProcessor;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.web.service.LightService;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 26/06/2015
+ */
+public class KustvaktCoreRestTest extends FastJerseyTest {
+
+    @BeforeClass
+    public static void configure() {
+        BeanConfiguration.loadClasspathContext();
+        addClass(LightService.class);
+    }
+
+    @Test
+    public void testFieldsInSearch() {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[base=Wort]").queryParam("ql", "poliqarp")
+                .get(ClientResponse.class);
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    @Test
+    public void testQuery() {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "Sonne prox/unit=word/distance<=5 Erde")
+                .queryParam("ql", "CQL").get(ClientResponse.class);
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    // in case no index is there, this will throw an error
+    @Ignore
+    @Test
+    public void testGetMatchInfoThrowsNoException() {
+        ClientResponse response = resource().path(API_VERSION)
+                .get(ClientResponse.class);
+    }
+
+    @Test
+    public void testGetStatsThrowsNoException() {
+        CollectionQueryProcessor pr = new CollectionQueryProcessor();
+        pr.process("corpusID=WPD & textClass=Sport");
+        Map map = new LinkedHashMap();
+        map.put("collection", pr.getRequestMap());
+        ClientResponse response = resource().path(API_VERSION).path("stats")
+                .post(ClientResponse.class, JsonUtils.toJSON(map));
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    @Test
+    public void testBuildQueryThrowsNoException() {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[base=Haus & surface=Hauses]")
+                .queryParam("ql", "poliqarp").queryParam("cutOff", "true")
+                .queryParam("page", "1").method("TRACE", ClientResponse.class);
+        assert ClientResponse.Status.OK.getStatusCode() == response.getStatus();
+    }
+
+    @Test
+    public void testQueryByNameThrowsNoException() {
+        ClientResponse response = resource().path(API_VERSION).path("corpus")
+                .path("WPD").path("search")
+                .queryParam("q", "[base=Haus & surface=Hauses]")
+                .queryParam("ql", "poliqarp").queryParam("cutOff", "true")
+                .queryParam("page", "1").get(ClientResponse.class);
+        System.out.println("RESPONSE " + response);
+    }
+
+}
diff --git a/src/test/java/RewriteTest.java b/src/test/java/RewriteTest.java
index 92e61fd..f06390e 100644
--- a/src/test/java/RewriteTest.java
+++ b/src/test/java/RewriteTest.java
@@ -1,8 +1,11 @@
+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.query.serialize.QuerySerializer;
 import de.ids_mannheim.korap.resource.LayerMapper;
 import de.ids_mannheim.korap.resource.RewriteProcessor;
-import de.ids_mannheim.korap.utils.CollectionQueryBuilder3;
+import de.ids_mannheim.korap.resource.rewrite.*;
+import de.ids_mannheim.korap.utils.JsonUtils;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -10,6 +13,7 @@
  * @author hanl
  * @date 18/06/2015
  */
+//todo: refactor and structure tests
 public class RewriteTest {
 
     private static String simple_add_query = "[pos=ADJA]";
@@ -18,42 +22,174 @@
     private static String complex_rewrite_query2 = "[orth=laufe/i & base!=Lauf]";
     private static String complex_rewrite_query3 = "[(base=laufen | base=gehen) & tt/pos=VVFIN]";
 
-    public RewriteTest() {
-
-    }
+    private static KustvaktConfiguration config;
 
     @BeforeClass
     public static void init() {
-        BeanConfiguration.loadFileContext(
-                "/Users/hanl/Projects/KorAP-project/KorAP-modules/Kustvakt-core/src/main/resources/default-config.xml");
+        BeanConfiguration.loadClasspathContext();
+        config = BeanConfiguration.getBeans().getConfiguration();
     }
 
     @Test
-    public void testQuery() {
+    public void testSimpleFoundryAddThrowsNoError() {
+        RewriteProcessor processor = new RewriteProcessor(config);
         QuerySerializer s = new QuerySerializer();
         s.setQuery(simple_add_query, "poliqarp");
-        System.out.println("query " + s.toJSON());
-
-        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
-        b.add("textClass=politik & corpusID=WPD");
-        System.out.println("collection query " + b.toJSON());
+        String result = processor.process(s.toJSON());
+        JsonNode node = JsonUtils.readTree(result);
+        assert !node.at("/query/wrap/foundry").isMissingNode();
     }
 
     @Test
-    public void testLayerMapper() {
-        LayerMapper m = new LayerMapper();
-        System.out.println("foundry " + m.findFoundry("lemma"));
-        System.out.println("foundry " + m.findFoundry("surface"));
-        System.out.println("foundry " + m.findFoundry("pos"));
+    public void testDefaultLayerMapperThrowsNoException() {
+        LayerMapper m = new LayerMapper(config);
+
+        assert m.findFoundry("lemma").equals(config.getDefault_lemma());
+        assert m.findFoundry("pos").equals(config.getDefault_pos());
+        assert m.findFoundry("surface").equals(config.getDefault_surface());
+        assert m.findFoundry("d").equals(config.getDefault_dep());
+        assert m.findFoundry("c").equals(config.getDefault_const());
     }
 
     @Test
-    public void testRewrite() {
-        RewriteProcessor processor = new RewriteProcessor();
-
+    public void testFoundryInjectPosNoErrors() {
         QuerySerializer s = new QuerySerializer();
-        s.setQuery(complex_rewrite_query3, "poliqarp");
-        System.out.println("query " + s.toJSON());
-        System.out.println("finished node " + processor.process(s.toJSON()));
+        RewriteHandler handler = new RewriteHandler();
+        s.setQuery("[pos=ADJA]", "poliqarp");
+        handler.add(new FoundryInject(config));
+        String result = handler.apply(s.toJSON(), null);
+        JsonNode node = JsonUtils.readTree(result);
+        assert !node.at("/query/wrap/foundry").isMissingNode();
+        assert !node.at("/query/wrap/rewrites").isMissingNode();
+        assert node.at("/query/wrap/rewrites/0/@type").asText()
+                .equals("koral:rewrite");
     }
+
+    @Test
+    public void testFoundryInjectJoinedQueryNoErrors() {
+        QuerySerializer s = new QuerySerializer();
+        RewriteHandler handler = new RewriteHandler();
+        s.setQuery("[orth=laufe/i & base!=Lauf]", "poliqarp");
+        handler.add(new FoundryInject(config));
+        String result = handler.apply(s.toJSON(), null);
+        JsonNode node = JsonUtils.readTree(result);
+        assert node.at("/query/wrap/@type").asText().equals("koral:termGroup");
+        assert !node.at("/query/wrap/operands/0/foundry").isMissingNode();
+        assert !node.at("/query/wrap/operands/0/rewrites").isMissingNode();
+        assert !node.at("/query/wrap/operands/1/foundry").isMissingNode();
+        assert !node.at("/query/wrap/operands/1/rewrites").isMissingNode();
+    }
+
+    @Test
+    public void testFoundryInjectGroupedQueryNoErrors() {
+        QuerySerializer s = new QuerySerializer();
+        RewriteHandler handler = new RewriteHandler();
+        s.setQuery("[(base=laufen | base=gehen) & tt/pos=VVFIN]", "poliqarp");
+        handler.add(new FoundryInject(config));
+        String result = handler.apply(s.toJSON(), null);
+        JsonNode node = JsonUtils.readTree(result);
+
+        assert node.at("/query/wrap/@type").asText().equals("koral:termGroup");
+        assert !node.at("/query/wrap/operands/0/operands/0/foundry")
+                .isMissingNode();
+        assert !node.at("/query/wrap/operands/0/operands/0/rewrites")
+                .isMissingNode();
+        assert !node.at("/query/wrap/operands/0/operands/1/foundry")
+                .isMissingNode();
+        assert !node.at("/query/wrap/operands/0/operands/1/rewrites")
+                .isMissingNode();
+
+        assert !node.at("/query/wrap/operands/1/foundry").isMissingNode();
+        assert node.at("/query/wrap/operands/1/rewrites").isMissingNode();
+    }
+
+    @Test
+    public void testCollectionNodeRemoveCorpusIdNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection("textClass=politik & corpusID=WPD");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/operands").size() == 1;
+    }
+
+    @Test
+    public void testCollectionNodeRemoveAllCorpusIdNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection("corpusID=BRZ13 & corpusID=WPD");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/operands").size() == 0;
+    }
+
+    @Test
+    public void testCollectionNodeRemoveGroupedCorpusIdNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection(
+                "(corpusID=BRZ13 & textClass=Wissenschaft) & corpusID=WPD");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+
+        assert node.at("/collection/operands/0/@type").asText()
+                .equals("koral:docGroup");
+        assert node.at("/collection/operands/0/operands/0/key").asText()
+                .equals("textClass");
+    }
+
+    //fixme: will probably fail when one doc groups are being refactored
+    @Test
+    public void testCollectionCleanEmptyDocGroupNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        handler.add(new CollectionCleanupFilter());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection(
+                "(corpusID=BRZ13 & corpusID=WPD) & textClass=Wissenschaft & textClass=Sport");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/@type").asText().equals("koral:docGroup");
+        assert node.at("/collection/operands").size() == 2;
+        assert node.at("/collection/operands/0/key").asText()
+                .equals("textClass");
+        assert node.at("/collection/operands/1/key").asText()
+                .equals("textClass");
+    }
+
+    @Test
+    public void testCollectionCleanMoveOneDocFromGroupUpNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        handler.add(new CollectionCleanupFilter());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection("(corpusID=BRZ13 & textClass=Wissenschaft)");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/@type").asText().equals("koral:doc");
+    }
+
+    @Test
+    public void testCollectionCleanEmptyGroupAndMoveOneDocFromGroupUpNoErrors() {
+        RewriteHandler handler = new RewriteHandler();
+        handler.add(new CollectionConstraint());
+        handler.add(new CollectionCleanupFilter());
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery(simple_add_query, "poliqarp");
+        s.setCollection(
+                "(corpusID=BRZ13 & corpusID=WPD) & textClass=Wissenschaft");
+        String result = s.toJSON();
+        JsonNode node = JsonUtils.readTree(handler.apply(result, null));
+        assert node.at("/collection/@type").asText().equals("koral:doc");
+        assert node.at("/collection/key").asText().equals("textClass");
+    }
+
 }