diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/AuditingIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/db/AuditingIface.java
similarity index 97%
rename from src/main/java/de/ids_mannheim/korap/interfaces/AuditingIface.java
rename to src/main/java/de/ids_mannheim/korap/interfaces/db/AuditingIface.java
index 18a616f..ed21e60 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/AuditingIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/db/AuditingIface.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.interfaces;
+package de.ids_mannheim.korap.interfaces.db;
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
 import de.ids_mannheim.korap.user.User;
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/EntityHandlerIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/db/EntityHandlerIface.java
similarity index 96%
rename from src/main/java/de/ids_mannheim/korap/interfaces/EntityHandlerIface.java
rename to src/main/java/de/ids_mannheim/korap/interfaces/db/EntityHandlerIface.java
index aed2871..f349f23 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/EntityHandlerIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/db/EntityHandlerIface.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.interfaces;
+package de.ids_mannheim.korap.interfaces.db;
 
 import de.ids_mannheim.korap.exceptions.EmptyResultException;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/PersistenceClient.java b/src/main/java/de/ids_mannheim/korap/interfaces/db/PersistenceClient.java
similarity index 95%
rename from src/main/java/de/ids_mannheim/korap/interfaces/PersistenceClient.java
rename to src/main/java/de/ids_mannheim/korap/interfaces/db/PersistenceClient.java
index 07d53c7..c21d941 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/PersistenceClient.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/db/PersistenceClient.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.interfaces;
+package de.ids_mannheim.korap.interfaces.db;
 
 import lombok.Getter;
 
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/PolicyHandlerIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/db/PolicyHandlerIface.java
similarity index 98%
rename from src/main/java/de/ids_mannheim/korap/interfaces/PolicyHandlerIface.java
rename to src/main/java/de/ids_mannheim/korap/interfaces/db/PolicyHandlerIface.java
index 122970f..15e4296 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/PolicyHandlerIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/db/PolicyHandlerIface.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.interfaces;
+package de.ids_mannheim.korap.interfaces.db;
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.resources.KustvaktResource;
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/ResourceOperationIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/db/ResourceOperationIface.java
similarity index 96%
rename from src/main/java/de/ids_mannheim/korap/interfaces/ResourceOperationIface.java
rename to src/main/java/de/ids_mannheim/korap/interfaces/db/ResourceOperationIface.java
index fa0bf35..260e928 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/ResourceOperationIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/db/ResourceOperationIface.java
@@ -1,4 +1,4 @@
-package de.ids_mannheim.korap.interfaces;
+package de.ids_mannheim.korap.interfaces.db;
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.resources.KustvaktResource;
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
new file mode 100644
index 0000000..a21d767
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/KustvaktEncryption.java
@@ -0,0 +1,483 @@
+package de.ids_mannheim.korap.interfaces.defaults;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.user.User;
+import edu.emory.mathcs.backport.java.util.Collections;
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.binary.Base64;
+import org.mindrot.jbcrypt.BCrypt;
+import org.owasp.esapi.ESAPI;
+import org.owasp.esapi.Randomizer;
+import org.owasp.esapi.Validator;
+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;
+import java.lang.reflect.Modifier;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class KustvaktEncryption implements EncryptionIface {
+
+    private static final String ALGORITHM = "SHA-256";
+    private static Logger jlog = LoggerFactory
+            .getLogger(KustvaktEncryption.class);
+    // todo: disable this
+    private static final String PASSWORD_SALT_FIELD = "accountCreation";
+
+    private final boolean nullable;
+    private final Validator validator;
+    private final Randomizer randomizer;
+    private KustvaktConfiguration config;
+
+    public KustvaktEncryption(KustvaktConfiguration config) {
+        jlog.info("initializing KorAPEncryption implementation");
+        this.nullable = false;
+        this.validator = DefaultValidator.getInstance();
+        this.randomizer = ESAPI.randomizer();
+        this.config = config;
+    }
+
+    public static boolean matchTokenByteCode(Object param) {
+        if (!(param instanceof String))
+            return false;
+        String token = (String) param;
+        byte[] bytes = token.getBytes();
+        return 64 == bytes.length;
+    }
+
+    private String encodeBase(byte[] bytes) throws EncoderException {
+        return Base64.encodeBase64String(bytes);
+    }
+
+    @Override
+    public String encodeBase() {
+        try {
+            return encodeBase(this.createSecureRandom(24));
+        }catch (EncoderException e) {
+            return "";
+        }
+    }
+
+    public String produceSecureHash(String input) {
+        return produceSecureHash(input, "");
+    }
+
+    @Override
+    public String produceSecureHash(String input, String salt) {
+        String hashString = "";
+        switch (config.getEncryption()) {
+            case ESAPICYPHER:
+                try {
+                    hashString = hash(input, salt);
+                }catch (NoSuchAlgorithmException e) {
+                    jlog.error("there was an encryption error!", e);
+                    return null;
+                }catch (Exception e) {
+                    jlog.error("there was an error!", e);
+                    return null;
+                }
+                break;
+            case SIMPLE:
+                try {
+                    MessageDigest md = MessageDigest.getInstance("SHA-256");
+                    md.update(input.getBytes("UTF-8"));
+                    byte[] digest = md.digest();
+
+                    for (byte b : digest)
+                        hashString += String.format("%02x", b);
+                }catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
+                    e.printStackTrace();
+                }
+                break;
+            case BCRYPT:
+                hashString = bcryptHash(input, salt);
+                break;
+            default:
+                jlog.warn("Invalid value: {}", config.getEncryption());
+                break;
+        }
+        return hashString;
+    }
+
+    public String hash(String text, String salt) throws Exception {
+        byte[] bytes;
+
+        MessageDigest md = MessageDigest.getInstance(ALGORITHM);
+        md.reset();
+        md.update(ESAPI.securityConfiguration().getMasterSalt());
+        md.update(salt.getBytes());
+        md.update(text.getBytes());
+
+        bytes = md.digest();
+        for (int i = 0; i < 234; ++i) {
+            md.reset();
+            bytes = md.digest(bytes);
+        }
+        String coding = ESAPI.encoder().encodeForBase64(bytes, false);
+        return coding;
+    }
+
+    @Override
+    public String hash(String input) {
+        String hashString = "";
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance("SHA-256");
+            md.update(input.getBytes("UTF-8"));
+        }catch (NoSuchAlgorithmException e) {
+            return "";
+        }catch (UnsupportedEncodingException e) {
+            return "";
+        }
+
+        byte[] digest = md.digest();
+
+        for (byte b : digest) {
+            hashString += String.format("%02x", b);
+        }
+        return hashString;
+    }
+
+    /**
+     * // some sort of algorithm to create token and isSystem regularly the integrity
+     * // of the token
+     * public String createAuthToken() {
+     * final byte[] rNumber = SecureRGenerator
+     * .getNextSecureRandom(SecureRGenerator.TOKEN_RANDOM_SIZE);
+     * String hash;
+     * try {
+     * hash = produceSimpleHash(SecureRGenerator.toHex(rNumber));
+     * } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+     * return "";
+     * }
+     * return hash;
+     * }
+     */
+
+    private byte[] createSecureRandom(int size) {
+        return SecureRGenerator.getNextSecureRandom(size);
+    }
+
+    @Override
+    public String createToken(boolean hash, Object... obj) {
+        StringBuffer b = new StringBuffer();
+        try {
+            for (Object o : obj) {
+                b.append(" | ");
+                b.append(o);
+            }
+            if (hash)
+                return encodeBase(hash(b.toString().trim()).getBytes());
+            else
+                return encodeBase(b.toString().trim().getBytes());
+        }catch (EncoderException e) {
+            return "";
+        }
+
+    }
+
+    @Override
+    public String createToken() {
+        String encoded;
+        String v = randomizer
+                .getRandomString(SecureRGenerator.TOKEN_RANDOM_SIZE,
+                        SecureRGenerator.toHex(createSecureRandom(64))
+                                .toCharArray());
+        encoded = hash(v);
+        jlog.trace("creating new token {}", encoded);
+        return encoded;
+    }
+
+    @Override
+    public String createID(Object... obj) {
+        final byte[] rNumber = SecureRGenerator
+                .getNextSecureRandom(SecureRGenerator.CORPUS_RANDOM_SIZE);
+        if (obj.length != 0) {
+            ArrayList s = new ArrayList();
+            Collections.addAll(s, obj);
+            obj = s.toArray();
+        }else {
+            obj = new Object[1];
+            obj[0] = rNumber;
+        }
+        return createToken(false, obj);
+    }
+
+    @Override
+    public boolean checkHash(String plain, String hash, String salt) {
+        String pw = "";
+        switch (config.getEncryption()) {
+            case ESAPICYPHER:
+                pw = produceSecureHash(plain, salt);
+                break;
+            case BCRYPT:
+                try {
+                    return BCrypt.checkpw(plain, hash);
+                }catch (IllegalArgumentException e) {
+                    return false;
+                }
+            case SIMPLE:
+                pw = hash(plain);
+                break;
+        }
+        return pw.equals(hash);
+    }
+
+    @Override
+    public boolean checkHash(String plain, String hash) {
+        switch (config.getEncryption()) {
+            case ESAPICYPHER:
+                return produceSecureHash(plain).equals(hash);
+            case BCRYPT:
+                try {
+                    return BCrypt.checkpw(plain, hash);
+                }catch (IllegalArgumentException e) {
+                    return false;
+                }
+            case SIMPLE:
+                return hash(plain).equals(hash);
+        }
+        return false;
+    }
+
+    @Override
+    public String getSalt(User user) {
+        Class u = user.getClass();
+        Field field;
+        try {
+            field = u.getSuperclass().getDeclaredField(PASSWORD_SALT_FIELD);
+        }catch (NoSuchFieldException e) {
+            try {
+                field = u.getDeclaredField(PASSWORD_SALT_FIELD);
+            }catch (NoSuchFieldException e1) {
+                // do nothing
+                e.printStackTrace();
+                return null;
+            }
+        }
+        try {
+            field.setAccessible(true);
+            String value = String.valueOf(field.get(user));
+            field.setAccessible(false);
+            return value;
+        }catch (IllegalAccessException e) {
+            // do nothing
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public Map<String, Object> validateMap(Map<String, Object> map)
+            throws KustvaktException {
+        Map<String, Object> safeMap = new HashMap<>();
+        if (map != null) {
+            for (Map.Entry<String, Object> entry : map.entrySet()) {
+                Object value = null;
+                if (entry.getValue() instanceof String) {
+                    value = validateString((String) entry.getValue());
+
+                }else if (entry.getValue() instanceof List) {
+                    List list = (List) entry.getValue();
+                    for (Object v : list) {
+                        if (v instanceof String)
+                            validateString((String) v);
+                    }
+
+                    if (((List) entry.getValue()).size() == 1)
+                        value = list.get(0);
+                    else
+                        value = list;
+                }
+                safeMap.put(entry.getKey(), value);
+            }
+        }
+        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);
+        String s;
+        try {
+            s = validator.getValidInput(descr, input, type, length, nullable);
+        }catch (ValidationException e) {
+            jlog.error(
+                    "String value did not validate ('{}') with validation type {}",
+                    new Object[] { input, type, e.getMessage() });
+            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
+                    "invalid string of type " + type, input);
+        }
+        return s;
+    }
+
+    @Override
+    public String validateString(String input) throws KustvaktException {
+        if (input.contains("@")) {
+            return validateEmail(input);
+        }else
+            return validateString("Safe String", input, "SafeString",
+                    config.getValidationStringLength(), nullable);
+    }
+
+    @Override
+    public String validateEmail(String email) throws KustvaktException {
+        jlog.debug("validating email entry '{}'", email);
+        return validateString("Email", email, "Email",
+                config.getValidationEmaillength(), nullable);
+    }
+
+    @Override
+    public String validateIPAddress(String ipaddress) throws KustvaktException {
+        jlog.debug("validating IP address entry '{}'", ipaddress);
+        return validateString("IP Address", ipaddress, "IPAddress",
+                config.getValidationStringLength(), nullable);
+    }
+
+    @Override
+    public void validate(Object instance) throws KustvaktException {
+        if (instance == null)
+            return;
+        try {
+            validateStringField(instance.getClass().getDeclaredFields(),
+                    instance);
+            validateStringField(
+                    instance.getClass().getSuperclass().getDeclaredFields(),
+                    instance);
+        }catch (IllegalAccessException e) {
+            jlog.error("object value did not validate", e.getMessage());
+            throw new KustvaktException(StatusCodes.PARAMETER_VALIDATION_ERROR,
+                    "object could not be validated", instance.toString());
+        }
+    }
+
+    //fixme: fix validation algorithm
+    @Override
+    public String validatePassphrase(String pw) throws KustvaktException {
+        String safe_string = validateString(pw);
+        String pw_conf;
+        try {
+            pw_conf = validator
+                    .getValidInput("User Password", safe_string, "Password", 20,
+                            false);
+        }catch (ValidationException e) {
+            jlog.error("password value did not validate", e.getMessage());
+            throw new KustvaktException(StatusCodes.PARAMETER_VALIDATION_ERROR,
+                    "password did not validate", "password");
+        }
+        return pw_conf;
+    }
+
+    //FIXME: currently all sets are skipped during validation (since users should not be allowed to edit those sets anyway,
+    //I think we will be safe here
+    private void validateStringField(Field[] fields, Object instance)
+            throws KustvaktException, IllegalAccessException {
+        for (Field field : fields) {
+            boolean priv = false;
+            if (field.getType().isAssignableFrom(String.class)) {
+                if (Modifier.isPrivate(field.getModifiers())) {
+                    priv = true;
+                    field.setAccessible(true);
+                }
+                if (field.getName().equals("password") | Modifier
+                        .isFinal(field.getModifiers()))
+                    continue;
+                String val = (String) field.get(instance);
+                if (val != null) {
+                    String[] set = val.split(";");
+                    if (set.length > 1)
+                        continue;
+                }
+                String safe;
+                if (!field.getName().equals("email"))
+                    safe = validateString("Safe String", val, "SafeString",
+                            config.getValidationStringLength(), true);
+                else
+                    safe = validateString("User Email", val, "Email",
+                            config.getValidationEmaillength(), true);
+                field.set(instance, safe == null ? "" : safe);
+
+                if (priv) {
+                    field.setAccessible(false);
+                }
+            }
+        }
+    }
+
+    private String bcryptHash(String text, String salt) {
+        if (salt == null || salt.isEmpty())
+            salt = BCrypt.gensalt(config.getLoadFactor());
+        return BCrypt.hashpw(text, salt);
+    }
+
+    @Override
+    public String toString() {
+        return this.getClass().getCanonicalName();
+    }
+
+    public static class SecureRGenerator {
+        private static final String SHA1_PRNG = "SHA1PRNG";
+        protected static final int DEFAULT_RANDOM_SIZE = 128;
+        protected static final int TOKEN_RANDOM_SIZE = 128;
+        protected static final int USERID_RANDOM_SIZE = 64;
+        protected static final int CORPUS_RANDOM_SIZE = 48;
+        private static final char[] HEX_DIGIT = { '0', '1', '2', '3', '4', '5',
+                '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'z', 'x', 'h',
+                'q', 'w' };
+        private static final SecureRandom sRandom__;
+
+        static {
+            try {
+                sRandom__ = SecureRandom.getInstance("SHA1PRNG");
+            }catch (NoSuchAlgorithmException e) {
+                throw new Error(e);
+            }
+        }
+
+        public static byte[] getNextSecureRandom(int bits) {
+            if (bits % 8 != 0) {
+                throw new IllegalArgumentException(
+                        "Size is not divisible by 8!");
+            }
+
+            byte[] bytes = new byte[bits / 8];
+
+            sRandom__.nextBytes(bytes);
+
+            return bytes;
+        }
+
+        public static String toHex(byte[] bytes) {
+            if (bytes == null) {
+                return null;
+            }
+
+            StringBuilder buffer = new StringBuilder(bytes.length * 2);
+            for (byte thisByte : bytes) {
+                buffer.append(byteToHex(thisByte));
+            }
+
+            return buffer.toString();
+        }
+
+        private static String byteToHex(byte b) {
+            char[] array = { HEX_DIGIT[(b >> 4 & 0xF)], HEX_DIGIT[(b & 0xF)] };
+            return new String(array);
+        }
+    }
+
+}
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
new file mode 100644
index 0000000..0c91ac0
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/resource/rewrite/IdWriter.java
@@ -0,0 +1,8 @@
+package de.ids_mannheim.korap.resource.rewrite;
+
+/**
+ * @author hanl
+ * @date 25/09/2015
+ */
+public class IdWriter {
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
new file mode 100644
index 0000000..d260b65
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
@@ -0,0 +1,808 @@
+package de.ids_mannheim.korap.security.ac;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.exceptions.dbException;
+import de.ids_mannheim.korap.ext.interfaces.PolicyHandlerIface;
+import de.ids_mannheim.korap.ext.resource.KorAPResource;
+import de.ids_mannheim.korap.ext.resource.ResourceFactory;
+import de.ids_mannheim.korap.ext.security.types.Parameter;
+import de.ids_mannheim.korap.ext.security.types.PolicyCondition;
+import de.ids_mannheim.korap.ext.security.types.SecurityPolicy;
+import de.ids_mannheim.korap.interfaces.PersistenceClient;
+import de.ids_mannheim.korap.user.Attributes;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.BooleanUtils;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
+import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.ResultSetExtractor;
+import org.springframework.jdbc.core.RowCallbackHandler;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author hanl
+ * @date 14/01/2014
+ */
+// todo: transactions and exception management
+public class PolicyDao implements PolicyHandlerIface {
+
+    private NamedParameterJdbcTemplate jdbcTemplate;
+
+    public PolicyDao(PersistenceClient client) {
+        this.jdbcTemplate = (NamedParameterJdbcTemplate) client.getSource();
+    }
+
+    /**
+     * @param policy
+     * @param user
+     * @return int to indicate the rows updated/inserted
+     * @throws KustvaktException
+     */
+    // fixme: better way of dealing with this?
+    // fixme: enable needs to be set specifically for mysql db
+    @Override
+    public int createPolicy(SecurityPolicy policy, User user)
+            throws KustvaktException {
+        String sql =
+                "INSERT INTO policy_store (target_id, creator, created, posix, enable, expire, iprange)"
+                        + " SELECT id, :creator, :cr, :posix, :en, :exp, :ip FROM resource_store WHERE persistent_id=:target;";
+
+        if (policy.getTarget() == null)
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.MISSING_POLICY_TARGET, policy.toString());
+
+        if (policy.getConditions().isEmpty())
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.MISSING_POLICY_CONDITIONS);
+
+        if (policy.getPermissionByte() == 0)
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.MISSING_POLICY_PERMISSION);
+
+        KeyHolder keyHolder = new GeneratedKeyHolder();
+        MapSqlParameterSource np = new MapSqlParameterSource();
+        np.addValue("target", policy.getTarget());
+        if (policy.getContext().getEnd() != 0L)
+            np.addValue("exp", new Timestamp(policy.getContext().getEnd()));
+        else
+            np.addValue("exp", null);
+        np.addValue("en", new Timestamp(policy.getContext().getStart()));
+        np.addValue("posix", policy.getPermissionByte());
+        np.addValue("cr", new Timestamp(TimeUtils.getNow().getMillis()));
+        np.addValue("creator", user.getId());
+        np.addValue("ip", policy.getContext().getIpmask());
+
+        try {
+            mapConditionsToUsers(policy, user);
+            this.jdbcTemplate.update(sql, np, keyHolder, new String[] { "id" });
+            policy.setID(keyHolder.getKey().intValue());
+            this.mapConstraints(policy);
+            return policy.getID();
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (INSERT) not possible for '{}' for user '{}'",
+                            policy.toString(), user.getId());
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.DB_INSERT_FAILED, policy.toString());
+        }
+    }
+
+    /**
+     * should also include a remove operation, so removed policy constraints
+     *
+     * @param policy
+     * @return
+     * @throws KustvaktException
+     */
+    // benchmark this!
+    @Override
+    public void mapConstraints(SecurityPolicy policy) throws KustvaktException {
+        final String cond = "INSERT INTO group_ref (group_id, policy_id) VALUES (:group, :policyID);";
+        final String remove = "DELETE FROM group_ref WHERE group_id=:group and policy_id=:policyID;";
+        try {
+            List<PolicyCondition> conditions = policy.getConditions();
+            int idx = 0;
+            if (!policy.getRemoved().isEmpty()) {
+                MapSqlParameterSource[] sources_removed = new MapSqlParameterSource[policy
+                        .getRemoved().size()];
+                for (Integer toremove : policy.getRemoved()) {
+                    MapSqlParameterSource source = new MapSqlParameterSource();
+                    source.addValue("group",
+                            conditions.get(toremove).getSpecifier());
+                    source.addValue("policyID", policy.getID());
+                    sources_removed[idx++] = source;
+                }
+                this.jdbcTemplate.batchUpdate(remove, sources_removed);
+            }
+
+            if (!policy.getAdded().isEmpty()) {
+                idx = 0;
+                MapSqlParameterSource[] sources = new MapSqlParameterSource[policy
+                        .getAdded().size()];
+                for (Integer add : policy.getAdded()) {
+                    MapSqlParameterSource source = new MapSqlParameterSource();
+                    source.addValue("group",
+                            conditions.get(add).getSpecifier());
+                    source.addValue("policyID", policy.getID());
+                    sources[idx++] = source;
+                }
+                this.jdbcTemplate.batchUpdate(cond, sources);
+            }
+            policy.clear();
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (MAPPING POLICY CONDITIONS) not possible for '{}' for user '{}'",
+                            policy.toString(), policy.getCreator());
+            // throwing an error here is not recommended
+            //            throw new dbException(policy.getCreator(), "policy_store",
+            //                    StatusCodes.DB_INSERT_FAILED, policy.toString());
+        }
+    }
+
+    // todo: check transactional behaviour! --> rollback
+    private void mapConditionsToUsers(SecurityPolicy policy, User user)
+            throws KustvaktException {
+        for (PolicyCondition cond : policy.getConditions()) {
+            MapSqlParameterSource param = new MapSqlParameterSource();
+            param.addValue("name", cond.getSpecifier());
+            param.addValue("userid", user.getId());
+
+            try {
+                final Integer[] results = new Integer[2];
+                jdbcTemplate
+                        .query("SELECT COUNT(*) as total, (select count(*) from group_users where user_id=:userid and "
+                                        + "group_id=:name) as users FROM group_store WHERE name=:name",
+                                param, new RowCallbackHandler() {
+                                    @Override
+                                    public void processRow(ResultSet rs)
+                                            throws SQLException {
+                                        results[0] = rs.getInt("total");
+                                        results[1] = rs.getInt("users");
+                                    }
+                                });
+
+                boolean admin = false;
+                if (results[0] == 0) {
+                    admin = true;
+                    this.createCondition(cond, user);
+                }
+                if (results[1] == 0)
+                    this.addToCondition(Arrays.asList(user.getUsername()), cond,
+                            admin);
+            }catch (DataAccessException e) {
+                KustvaktLogger.SECURITY_LOGGER
+                        .error("Operation (SELECT) not possible for '{}' for user '{}'",
+                                policy.getTarget(), user.getId());
+                throw new dbException(user.getId(), "policy_store",
+                        StatusCodes.DB_GET_FAILED, policy.toString());
+            }
+        }
+    }
+
+    // fixme: does not compare permissions. parent can still disregard policy because of missing permisssions
+    @Override
+    public List<SecurityPolicy>[] getPolicies(Integer target, final User user,
+            Byte perm) {
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("target", target);
+        param.addValue("userid", user.getId());
+        param.addValue("perm", perm);
+        param.addValue("en", new Timestamp(TimeUtils.getNow().getMillis()));
+
+        String sql_new =
+                "select pv.*, pv.perm & :perm as allowed, rh.depth, (select max(depth) from resource_tree \n"
+                        +
+                        "where child_id=rh.child_id) as max_depth from policy_view as pv "
+                        +
+                        "inner join resource_tree as rh on rh.parent_id=pv.id "
+                        +
+                        "where rh.child_id=:target and pv.enable <= :en and (pv.expire > :en or pv.expire is NULL) and "
+                        +
+                        "(pv.group_id='self' or pv.group_id in (select g.group_id from group_users as g where g.user_id=:userid)) and "
+                        +
+                        "(select sum(distinct depth) from resource_tree where child_id=rh.child_id) = "
+                        +
+                        "(select sum(distinct res.depth) from p_view as pos inner join resource_tree as res on res.parent_id=pos.id where (pos.group_id in (select g.group_id from group_users as g "
+                        +
+                        "where g.user_id=:userid) or pos.group_id='self') and res.child_id=rh.child_id group by child_id);";
+
+        try {
+            return this.jdbcTemplate.query(sql_new, param,
+                    new ResultSetExtractor<List<SecurityPolicy>[]>() {
+
+                        @Override
+                        public List<SecurityPolicy>[] extractData(ResultSet rs)
+                                throws SQLException, DataAccessException {
+                            return SecurityRowMappers.mapping(rs, user);
+                        }
+                    });
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Permission Denied for retrieval for '{}' for user '{}'",
+                            target, user.getId());
+            return new List[2];
+        }
+    }
+
+    @Override
+    public List<SecurityPolicy>[] getPolicies(String target, final User user,
+            Byte perm) {
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("target", target);
+        param.addValue("userid", user.getId());
+        param.addValue("perm", perm);
+        param.addValue("en", new Timestamp(TimeUtils.getNow().getMillis()));
+
+        // fixme: missing constraint of user group membership!
+        String sql_new = "select pv.*, pv.perm & :perm as allowed, " +
+                "rh.depth, (select max(depth) from resource_tree " +
+                "where child_id=rh.child_id) as max_depth from p_view as pv " +
+                "inner join resource_tree as rh on rh.parent_id=pv.id " +
+                "where rh.child_id=(select id from resource_store where persistentID=:target) and "
+                +
+                "pv.enable <= :en and (pv.expire > :en or pv.expire is NULL) and "
+                +
+                "(pv.group_id='self' or pv.group_id in (select g.group_id from group_users as g where g.userid=:userid)) and "
+                +
+                "(select sum(distinct depth) from resource_tree where child_id=rh.child_id) = "
+                +
+                "(select sum(distinct res.depth) from p_view as pos inner join resource_tree as res on res.parent_id=pos.id where (pos.group_id in (select g.group_id from group_users "
+                +
+                "as g where g.userid=:userid) or pos.group_id='self') and res.child_id=rh.child_id group by child_id)";
+
+        try {
+            return this.jdbcTemplate.query(sql_new, param,
+                    new ResultSetExtractor<List<SecurityPolicy>[]>() {
+
+                        @Override
+                        public List<SecurityPolicy>[] extractData(ResultSet rs)
+                                throws SQLException, DataAccessException {
+                            return SecurityRowMappers.mapping(rs, user);
+                        }
+                    });
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Permission Denied for retrieval for '{}' for user '{}'",
+                            target, user.getId());
+            return new List[2];
+        }
+    }
+
+    @Override
+    public List<SecurityPolicy>[] findPolicies(String path, final User user,
+            Byte perm) {
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("path", StringUtils.buildSQLRegex(path));
+        param.addValue("userid", user.getId());
+        param.addValue("perm", perm);
+        param.addValue("en", new Timestamp(TimeUtils.getNow().getMillis()));
+
+        String sql_new = "select pv.*, pv.perm & :perm as allowed, " +
+                "rh.depth, (select max(depth) from resource_tree " +
+                "where child_id=rh.child_id) as max_depth from p_view as pv " +
+                "inner join resource_tree as rh on rh.parent_id=pv.id " +
+                "where rt.name_path regexp :path and " +
+                "pv.enable <= :en and (pv.expire > :en or pv.expire is NULL) and "
+                +
+                "(pv.group_id='self' or pv.group_id in (select g.group_id from group_users as g where g.userid=:userid)) and "
+                +
+                "(select sum(distinct depth) from resource_tree where child_id=rh.child_id) = "
+                +
+                "(select sum(distinct res.depth) from p_view as pos inner join resource_tree as res on res.parent_id=pos.id where (pos.group_id in (select g.group_id from group_users "
+                +
+                "as g where g.userid=:userid) or pos.group_id='self') and res.child_id=rh.child_id group by child_id)";
+
+        try {
+            return this.jdbcTemplate.query(sql_new, param,
+                    new ResultSetExtractor<List<SecurityPolicy>[]>() {
+
+                        @Override
+                        public List<SecurityPolicy>[] extractData(ResultSet rs)
+                                throws SQLException, DataAccessException {
+                            return SecurityRowMappers.mapping(rs, user);
+                        }
+                    });
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Permission Denied for retrieval for '{}' for user '{}'",
+                            path, user.getId());
+            return new List[2];
+        }
+    }
+
+    /**
+     * @param path  if set searches in path where the child element equals name. Also applicable for root resources!
+     * @param user
+     * @param clazz
+     * @return
+     */
+    //todo: not working yet!
+    // todo: does not concern itsself with location matching, ever!
+    @Override
+    public List<KorAPResource.Container> getDescending(String path,
+            final User user, Byte b, final Class<? extends KorAPResource> clazz)
+            throws KustvaktException {
+        final MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("userid", user.getId());
+        param.addValue("type", ResourceFactory.getResourceMapping(clazz));
+        param.addValue("part", "%" + path);
+        param.addValue("perm", b);
+
+        String sql;
+        if (path != null && !path.isEmpty()) {
+            sql = "select pv.*, pv.perm & :perm as allowed, rh.depth, rh.name_path, (select max(depth) from resource_tree \n"
+                    +
+                    "where child_id=rh.child_id) as max_depth from p_view as pv "
+                    +
+                    "inner join resource_tree as rh on rh.child_id=pv.id " +
+                    "where pv.type=:type and (rh.name_path like :part) and ((pv.creator=:userid and pv.group_id='self') or "
+                    +
+                    "(pv.group_id in (select g.group_id from group_users as g where g.userid=:userid) and "
+                    +
+                    "(select sum(distinct depth) from resource_tree where child_id=rh.child_id) = "
+                    +
+                    "(select sum(distinct depth) from p_view as pos inner join resource_tree as res on res.parent_id=pos.id "
+                    +
+                    "where pos.group_id in (select g.group_id from group_users as g where g.userid=:userid) "
+                    +
+                    "and res.child_id=rh.child_id group by child_id))) " +
+                    "group by pv.pid, pv.id having count(distinct pv.group_id) = "
+                    +
+                    "((select count(co.group_id) from group_ref as co where co.policyid=pv.pid) or "
+                    +
+                    "(select 1 from p_view as cp2 where cp2.group_id='self' and cp2.id=pv.id)) "
+                    +
+                    "order by rh.depth asc, pv.id desc;";
+        }else {
+            sql = "select pv.*, pv.perm & :perm as allowed, rh.depth, rh.name_path, (select max(depth) from resource_tree \n"
+                    +
+                    "where child_id=rh.child_id) as max_depth from p_view as pv "
+                    +
+                    "inner join resource_tree as rh on rh.child_id=pv.id " +
+                    "where pv.type=:type and ((pv.creator=:userid and pv.group_id='self') or "
+                    +
+                    "(pv.group_id in (select g.group_id from group_users as g where g.userid=:userid) and "
+                    +
+                    "(select sum(distinct depth) from resource_tree where child_id=rh.child_id) = "
+                    +
+                    "(select sum(distinct depth) from p_view as pos inner join resource_tree as res on res.parent_id=pos.id "
+                    +
+                    "where pos.group_id in (select g.group_id from group_users as g where g.userid=:userid) "
+                    +
+                    "and res.child_id=rh.child_id group by child_id))) " +
+                    "group by pv.pid, pv.id having count(distinct pv.group_id) = "
+                    +
+                    "((select count(co.group_id) from group_ref as co where co.policyid=pv.pid) or "
+                    +
+                    "(select 1 from p_view as cp2 where cp2.group_id='self' and cp2.id=pv.id)) "
+                    +
+                    "order by rh.depth asc, pv.id desc;";
+        }
+        try {
+            return this.jdbcTemplate.query(sql, param,
+                    new SecurityRowMappers.HierarchicalResultExtractor());
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Permission Denied for retrieval for path '{}' for user '{}'",
+                            path, user.getId());
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.DB_GET_FAILED, path, clazz.toString());
+        }
+    }
+
+    @Override
+    public List<KorAPResource.Container> getAscending(String name, User user,
+            Byte b, Class<? extends KorAPResource> clazz)
+            throws KustvaktException {
+        final MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("userid", user.getId());
+        param.addValue("type", ResourceFactory.getResourceMapping(clazz));
+        param.addValue("part", "%" + name);
+        param.addValue("perm", b);
+
+        String sql;
+        if (name != null && !name.isEmpty()) {
+            sql = "select pv.*, pv.perm & :perm as allowed, rh.depth, rh.name_path,\n"
+                    +
+                    "(select max(depth) from resource_tree \n" +
+                    "where child_id=rh.child_id) as max_depth from p_view as pv\n"
+                    +
+                    "inner join resource_tree as rh on rh.child_id=pv.id\n" +
+                    "where pv.id in (select rt.parent_id from resource_tree as rt inner join resource_store rs on rs.id=rt.child_id\n"
+                    +
+                    "where rs.type=:type and rt.name_path like :part) and ((pv.creator=:userid and pv.group_id='self') or\n"
+                    +
+                    "(pv.group_id in (select g.group_id from group_users as g where g.userid=:userid) and\n"
+                    +
+                    "(select sum(distinct depth) from resource_tree where child_id=rh.child_id) =\n"
+                    +
+                    "(select sum(distinct depth) from p_view as pos inner join resource_tree as res on res.parent_id=pos.id\n"
+                    +
+                    "where pos.group_id in (select g.group_id from group_users as g where g.userid=:userid)\n"
+                    +
+                    "and res.child_id=rh.child_id group by child_id)))\n" +
+                    "group by pv.pid, pv.id having count(distinct pv.group_id) = \n"
+                    +
+                    "case when pv.creator=:userid then 1 else (select count(distinct co.group_id) "
+                    +
+                    "from group_ref as co where co.policyid=pv.pid) end order by rh.depth desc, pv.id desc;";
+        }else {
+            sql = "select pv.*, pv.perm & :perm as allowed, rh.depth, rh.name_path,\n"
+                    +
+                    "(select max(depth) from resource_tree \n" +
+                    "where child_id=rh.child_id) as max_depth from p_view as pv\n"
+                    +
+                    "inner join resource_tree as rh on rh.child_id=pv.id\n" +
+                    "where pv.id in (select rt.parent_id from resource_tree as rt inner join resource_store rs on rs.id=rt.child_id\n"
+                    +
+                    "where rs.type=:type) and ((pv.creator=:userid and pv.group_id='self') or\n"
+                    +
+                    "(pv.group_id in (select g.group_id from group_users as g where g.userid=:userid) and\n"
+                    +
+                    "(select sum(distinct depth) from resource_tree where child_id=rh.child_id) =\n"
+                    +
+                    "(select sum(distinct depth) from p_view as pos inner join resource_tree as res on res.parent_id=pos.target_id\n"
+                    +
+                    "where pos.group_id in (select g.group_id from group_users as g where g.userid=:userid)\n"
+                    +
+                    "and res.child_id=rh.child_id group by child_id)))\n" +
+                    "group by pv.pid, pv.id having count(distinct pv.group_id) = \n"
+                    +
+                    "case when pv.creator=:userid then 1 else (select count(distinct co.group_id) "
+                    +
+                    "from group_ref as co where co.policyid=pv.pid) end order by rh.depth desc, pv.id desc;";
+        }
+        try {
+            return this.jdbcTemplate.query(sql, param,
+                    new SecurityRowMappers.HierarchicalResultExtractor());
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Permission Denied for retrieval for path '{}' for user '{}'",
+                            name, user.getId());
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.DB_GET_FAILED, name, clazz.toString());
+        }
+    }
+
+    // todo: return all resources or only leave nodes? --> currently only leaves are returned
+    // todo: access to leave node also means that the path to the root for that permission is allowed,
+    // todo: thus all upper resource access is as well allowed
+
+    //todo: remove not used context?! --> who is allowed to do so?
+    @Override
+    public int deletePolicy(SecurityPolicy policy, User user)
+            throws KustvaktException {
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("id", policy.getID());
+
+        try {
+            this.jdbcTemplate
+                    .update("DELETE FROM group_ref WHERE policyid=:id", param);
+            return this.jdbcTemplate
+                    .update("DELETE FROM policy_store WHERE id=:id", param);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (DELETE) not possible for '{}' for user '{}'",
+                            policy.toString(), user.getId());
+            throw new dbException(user.getId(), "policy_store, group_ref",
+                    StatusCodes.DB_DELETE_FAILED, policy.toString());
+        }
+    }
+
+    @Override
+    public void deleteResourcePolicies(String id, User user)
+            throws KustvaktException {
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("id", id);
+        String sql = "DELETE FROM policy_store WHERE target_id=:id;";
+        try {
+            this.jdbcTemplate.update(sql, param);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (DELETE) not possible for '{}' for user '{}'",
+                            id, user.getId());
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.DB_DELETE_FAILED, id);
+        }
+    }
+
+    @Override
+    public int updatePolicy(SecurityPolicy policy, User user)
+            throws KustvaktException {
+        MapSqlParameterSource np = new MapSqlParameterSource();
+        np.addValue("posix", policy.getPermissionByte());
+        np.addValue("en", policy.getContext().getStart());
+        np.addValue("ex", policy.getContext().getEnd());
+        np.addValue("id", policy.getID());
+
+        try {
+            int result = this.jdbcTemplate
+                    .update("UPDATE policy_store SET posix=:posix WHERE id=:id",
+                            np);
+            this.mapConstraints(policy);
+            return result;
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (UPDATE) not possible for '{}' for user '{}'",
+                            policy.toString(), user.getId());
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.DB_UPDATE_FAILED, policy.toString());
+        }
+    }
+
+    @Override
+    public int checkPolicy(SecurityPolicy policy, User user)
+            throws KustvaktException {
+        if (policy.getID() == -1)
+            return 0;
+
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("id", policy.getID());
+        String sql1 = "SELECT COUNT(*) FROM policy_store AS p WHERE p.id=:id;";
+
+        try {
+            return this.jdbcTemplate.queryForObject(sql1, param, Integer.class);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (SELECT) not possible for '{}' for user '{}'",
+                            policy.getTarget(), user.getId());
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.DB_GET_FAILED, policy.toString());
+        }
+    }
+
+    /**
+     * checks if the user is a member of the specified group. Additional ownership can be tested via boolean flag
+     *
+     * @param user
+     * @param group
+     * @param owner
+     * @return
+     * @throws KustvaktException
+     */
+    @Override
+    public int matchCondition(User user, String group, boolean owner)
+            throws KustvaktException {
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        param.addValue("userid", user.getId());
+        param.addValue("group", group);
+        param.addValue("isadmin", BooleanUtils.getBoolean(owner));
+        String sql;
+        if (owner) {
+            sql = "SELECT COUNT(*) FROM group_users AS gu INNER JOIN groupolicy_store AS gs "
+                    +
+                    "ON gs.name=gu.group_id WHERE gu.userID=:userid " +
+                    "AND gs.name=:group AND gu.admin=:isadmin;";
+        }else {
+            sql = "SELECT COUNT(*) FROM group_users AS gu INNER JOIN groupolicy_store AS gs "
+                    +
+                    "ON gs.name=gu.group_id WHERE gu.userID=:userid " +
+                    "AND gs.name=:group;";
+        }
+
+        try {
+            return this.jdbcTemplate.queryForObject(sql, param, Integer.class);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (SELECT) not possible for '{}' for user '{}'",
+                            group, user.getId());
+            throw new dbException(user.getId(), "policy_store",
+                    StatusCodes.DB_GET_FAILED, group);
+        }
+    }
+
+    private Integer createCondition(PolicyCondition condition, User user)
+            throws KustvaktException {
+        MapSqlParameterSource param = new MapSqlParameterSource();
+        KeyHolder key = new GeneratedKeyHolder();
+        param.addValue("name", condition.getSpecifier());
+        param.addValue("ex", condition.getFlags().get(Attributes.EXPORT));
+        param.addValue("qo", condition.getFlags().get(Attributes.QUERY_ONLY));
+        param.addValue("com", condition.getFlags().get(Attributes.COMMERCIAL));
+        param.addValue("sy", condition.getFlags().get(Attributes.SYM_USE));
+        param.addValue("ex", condition.getFlags().get(Attributes.LICENCE));
+        try {
+            this.jdbcTemplate
+                    .update("INSERT INTO group_store (name, sym_use, export, commercial) "
+                            + "VALUES (:name, :sy, :ex, :com);", param, key);
+            return key.getKey().intValue();
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (INSERT) not possible for '{}'",
+                            condition.toString());
+            throw new dbException(user.getId(), "group_store",
+                    StatusCodes.DB_INSERT_FAILED, condition.toString());
+        }
+    }
+
+    @Override
+    public int addToCondition(String username, PolicyCondition condition,
+            boolean admin) throws KustvaktException {
+        final String insert =
+                "INSERT INTO group_users (userID, group_id, admin) " +
+                        "VALUES ((SELECT id FROM korap_users " +
+                        "WHERE username=:username), :group, :status);";
+        try {
+            MapSqlParameterSource param = new MapSqlParameterSource();
+            param.addValue("group", condition.getSpecifier());
+            param.addValue("username", username);
+            param.addValue("status", BooleanUtils.getBoolean(admin));
+            return this.jdbcTemplate.update(insert, param);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (INSERT) not possible for '{}' for user '{}'",
+                            condition.toString(), username);
+            throw new dbException(null, "group_store",
+                    StatusCodes.DB_INSERT_FAILED, condition.toString());
+        }
+    }
+
+    /**
+     * @param usernames
+     * @param condition
+     * @param admin
+     * @return
+     * @throws KustvaktException userID and group_id have a unique constraint,
+     *                        thus: if any of the supplied users is already a member of the group, the entire chain will be broken!
+     */
+    //todo definitely needs rework
+    //todo: test the unique index constraints!
+    @Override
+    public int[] addToCondition(List<String> usernames,
+            PolicyCondition condition, boolean admin) throws KustvaktException {
+        MapSqlParameterSource[] sources = new MapSqlParameterSource[usernames
+                .size()];
+
+        //        todo: use unique index for that! problematic though --> why?
+        //        final String select = "select count(id) from group_users where userID=" +
+        //                "(select id from korap_users where username=:username) " +
+        //                "AND group_id=:group;";
+
+        //todo: use index to create uniqueness. how to batch?
+        final String insert =
+                "INSERT INTO group_users (user_id, group_id, admin) " +
+                        "VALUES ((SELECT id FROM korap_users " +
+                        "WHERE username=:username), :group, :status);";
+        try {
+            for (int idx = 0; idx < usernames.size(); idx++) {
+                if (usernames.get(idx) == null || usernames.get(idx).isEmpty())
+                    throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+
+                MapSqlParameterSource param = new MapSqlParameterSource();
+                param.addValue("group", condition.getSpecifier());
+                param.addValue("username", usernames.get(idx));
+                param.addValue("status", BooleanUtils.getBoolean(admin));
+                // if primary keys uniqueness is determined by both keys, then use
+                // that as checkup (may also be manageable via triggers)
+                //                if (this.jdbcTemplate
+                //                        .queryForObject(select, param, Integer.class) == 0)
+                sources[idx] = param;
+            }
+
+            // todo: only insert if user is not already a member of this group
+            //fixme: problem - unique constraints throws exception. skip that user entry?!
+            return this.jdbcTemplate.batchUpdate(insert, sources);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (INSERT) not possible for '{}' for user '{}'",
+                            condition.toString(), usernames);
+            throw new KustvaktException(e, StatusCodes.CONNECTION_ERROR);
+        }
+    }
+
+    @Override
+    public void removeFromCondition(List<String> usernames,
+            PolicyCondition condition) throws KustvaktException {
+        MapSqlParameterSource[] sources = new MapSqlParameterSource[usernames
+                .size()];
+        int idx = 0;
+        for (String s : usernames) {
+            MapSqlParameterSource param = new MapSqlParameterSource();
+            param.addValue("group", condition.getSpecifier());
+            param.addValue("username", s);
+            sources[idx++] = param;
+        }
+
+        final String del =
+                "DELETE FROM group_users WHERE group_id=:group AND userID=(SELECT id FROM "
+                        + "korap_users WHERE username=:username);";
+
+        try {
+            this.jdbcTemplate.batchUpdate(del, sources);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (DELETE) not possible for '{}' for user '{}'",
+                            condition.toString(), usernames);
+            throw new KustvaktException(e, StatusCodes.CONNECTION_ERROR);
+        }
+    }
+
+    @Override
+    public void createParamBinding(Parameter param) throws KustvaktException {
+        MapSqlParameterSource source = new MapSqlParameterSource();
+        source.addValue("key", param.getName());
+        source.addValue("policy", param.getPolicy().getID());
+        source.addValue("value", param.getValue());
+        source.addValue("flag", param.isEquality());
+
+        if (!parameterExists(param.getName()))
+            createParameter(param.getName(), "", param.getOwner());
+        final String insert =
+                "INSERT INTO param_map (paramID, policy_id, value, flag) VALUES ((SELECT id FROM param_store "
+                        + "WHERE p_key=:key), (SELECT id FROM policy_store WHERE id=:policy), :value, :flag);";
+        try {
+            this.jdbcTemplate.update(insert, source);
+        }catch (DataAccessException e) {
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (INSERT) not possible for '{}",
+                            param.toString());
+            throw new KustvaktException(e, StatusCodes.CONNECTION_ERROR);
+        }
+    }
+
+    @Override
+    public List<String> getUsersFromCondition(PolicyCondition condition)
+            throws KustvaktException {
+        MapSqlParameterSource source = new MapSqlParameterSource();
+        source.addValue("specifier", condition.getSpecifier());
+        final String sql1 =
+                "SELECT username FROM korap_users WHERE id IN (SELECT user_id FROM "
+                        + "group_users WHERE group_id=:specifier);";
+        try {
+            return this.jdbcTemplate.queryForList(sql1, source, String.class);
+        }catch (DataAccessException e) {
+            e.printStackTrace();
+            KustvaktLogger.SECURITY_LOGGER
+                    .error("Operation (SELECT) not possible for '{}'",
+                            condition.toString());
+            throw new KustvaktException(StatusCodes.CONNECTION_ERROR);
+        }
+    }
+
+    private boolean parameterExists(String key) {
+        MapSqlParameterSource source = new MapSqlParameterSource();
+        source.addValue("key", key);
+        final String select = "SELECT COUNT(*) FROM param_store WHERE p_key=:key;";
+        return this.jdbcTemplate.queryForObject(select, source, Integer.class)
+                == 1;
+    }
+
+    private void createParameter(String parameter, String value, Integer owner)
+            throws KustvaktException {
+        MapSqlParameterSource source = new MapSqlParameterSource();
+        source.addValue("name", parameter);
+        source.addValue("value", value);
+        source.addValue("owner", owner);
+        final String sql = "INSERT INTO param_store (p_key, p_value) VALUES (:name, :value);";
+        try {
+            this.jdbcTemplate.update(sql, source);
+        }catch (DataAccessException e) {
+            throw new KustvaktException(e, StatusCodes.CONNECTION_ERROR);
+        }
+    }
+
+    @Override
+    public void removeParamBinding(SecurityPolicy policy)
+            throws KustvaktException {
+        MapSqlParameterSource source = new MapSqlParameterSource();
+        source.addValue("id", policy.getID());
+        final String sql = "DELETE FROM param_map WHERE policy_id=:id";
+        try {
+            this.jdbcTemplate.update(sql, source);
+        }catch (DataAccessException e) {
+            throw new KustvaktException(e, StatusCodes.CONNECTION_ERROR);
+        }
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/SecurityRowMappers.java b/src/main/java/de/ids_mannheim/korap/security/ac/SecurityRowMappers.java
new file mode 100644
index 0000000..bf2de64
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/SecurityRowMappers.java
@@ -0,0 +1,239 @@
+package de.ids_mannheim.korap.security.ac;
+
+import de.ids_mannheim.korap.ext.resource.KorAPResource;
+import de.ids_mannheim.korap.ext.resource.ResourceFactory;
+import de.ids_mannheim.korap.ext.security.types.PolicyCondition;
+import de.ids_mannheim.korap.ext.security.types.PolicyContext;
+import de.ids_mannheim.korap.ext.security.types.SecurityPolicy;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.PrefixTreeMap;
+import lombok.Data;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.ResultSetExtractor;
+import org.springframework.jdbc.core.RowMapper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.*;
+
+/**
+ * @author hanl
+ * @date 03/03/2014
+ */
+public class SecurityRowMappers {
+
+    public static class PolicyRowMapper implements RowMapper<SecurityPolicy> {
+
+        @Override
+        public SecurityPolicy mapRow(ResultSet rs, int rowNum)
+                throws SQLException {
+            SecurityPolicy p = new SecurityPolicy();
+            p.setID(rs.getInt("pid")).setTarget(rs.getString("persistent_id"))
+                    .setPOSIX(rs.getString("perm"));
+
+            PolicyContext context = new PolicyContext();
+            context.setIPMask(rs.getString("iprange"));
+            Timestamp date = rs.getTimestamp("enable");
+            Timestamp date2 = rs.getTimestamp("expire");
+            if (date != null)
+                context.setEnableTime(date.getTime());
+            if (date2 != null)
+                context.setExpirationTime(date2.getTime());
+            //            context.addFlag("export", rs.getBoolean("export"));
+            //            context.addFlag("sym_use", rs.getInt("sym_use"));
+            p.setContext(context);
+            return p;
+        }
+    }
+
+    @Data
+    public static class FlagContext extends PolicyContext {
+
+        private Map<String, Object> flags;
+
+        public FlagContext() {
+            this.flags = new HashMap<>();
+        }
+
+        public FlagContext addFlag(String key, Object value) {
+            this.flags.put(key, value);
+            return this;
+        }
+
+        public FlagContext removeFlag(String key) {
+            this.flags.remove(key);
+            return this;
+        }
+
+        public FlagContext clearFlags() {
+            this.flags.clear();
+            return this;
+        }
+    }
+
+    public static List<SecurityPolicy>[] mapping(ResultSet rs, User user)
+            throws SQLException {
+        List<SecurityPolicy>[] policyArray = null;
+        List<Integer>[] idx = null;
+        while (rs.next()) {
+            // user has no permission here --> thus skip
+            if (rs.getInt("allowed") == 0)
+                continue;
+
+            if (policyArray == null) {
+                int v = rs.getInt("max_depth") + 1;
+                policyArray = new List[v];
+                idx = new List[v];
+            }
+
+            int depth = rs.getInt("depth");
+
+            if (policyArray[depth] == null) {
+                policyArray[depth] = new ArrayList<>();
+                idx[depth] = new ArrayList<>();
+            }
+
+            Integer pid = rs.getInt("pid");
+            String grouping = rs.getString("group_ref");
+            Integer index = idx[depth].indexOf(pid);
+
+            SecurityPolicy policy;
+            if (index == -1) {
+                if (pid == -1 && grouping.equalsIgnoreCase("self")) {
+                    policy = new SecurityPolicy.OwnerPolicy(
+                            rs.getString("persistent_id"), rs.getInt("creator"));
+                    policyArray[depth].add(0, policy);
+                    idx[depth].add(0, pid);
+                }else {
+                    policy = new SecurityRowMappers.PolicyRowMapper()
+                            .mapRow(rs, 0);
+                    policyArray[depth].add(policy);
+                    idx[depth].add(pid);
+
+                    //todo:
+                    //                    if (policy.isActive(user)) {
+                    //                        policyArray[depth].add(policy);
+                    //                        idx[depth].add(pid);
+                    //                    }
+                }
+            }else
+                policy = policyArray[depth].get(index);
+
+            PolicyCondition c = new PolicyCondition(rs.getString("group_ref"));
+            if (!policy.contains(c))
+                policy.addCondition(c);
+        }
+        return policyArray;
+    }
+
+    @Deprecated
+    public static List<SecurityPolicy>[] map(ResultSet rs) throws SQLException {
+        Map<Integer, SecurityPolicy>[] policyArray = null;
+        while (rs.next()) {
+            // user has no permission here!
+            if (rs.getInt("allowed") == 0)
+                continue;
+
+            if (policyArray == null)
+                policyArray = new Map[rs.getInt("max_depth") + 1];
+
+            int depth = rs.getInt("depth");
+            Map<Integer, SecurityPolicy> cursor = policyArray[depth];
+            if (cursor == null)
+                cursor = new HashMap<>();
+
+            Integer pid = rs.getInt("pid");
+            SecurityPolicy policy = cursor.get(pid);
+            if (policy == null) {
+                policy = new SecurityRowMappers.PolicyRowMapper().mapRow(rs, 0);
+                cursor.put(pid, policy);
+            }
+            PolicyCondition c = new PolicyCondition(rs.getString("group_ref"));
+
+            if (!policy.contains(c))
+                policy.addCondition(c);
+        }
+
+        List<SecurityPolicy>[] results;
+        if (policyArray == null) {
+            results = new List[1];
+            results[0] = new ArrayList<>();
+        }else {
+            results = new List[policyArray.length];
+            for (int idx = 0; idx < policyArray.length; idx++) {
+                if (policyArray[idx] != null)
+                    results[idx] = new ArrayList<>(policyArray[idx].values());
+                else
+                    results[idx] = new ArrayList<>();
+            }
+        }
+        return results;
+    }
+
+    public static class HierarchicalResultExtractor
+            implements ResultSetExtractor<List<KorAPResource.Container>> {
+
+        private boolean _withpid;
+
+        //        public HierarchicalResultExtractor(boolean wpid) {
+        //            this._withpid = wpid;
+        //        }
+
+        // todo: in order for this to work, all parent flags need to be matched in sql!
+        public List<KorAPResource.Container> extractData(ResultSet rs)
+                throws SQLException, DataAccessException {
+            // contains the container with the highest available name_path to retrieve partial matches!
+            PrefixTreeMap<KorAPResource.Container[]> containerMap = new PrefixTreeMap<>();
+            Map<Integer, SecurityPolicy> trace = new HashMap<>();
+
+            while (rs.next()) {
+                KorAPResource.Container[] cursor;
+                Integer pid = rs.getInt("pid");
+
+                SecurityPolicy policy = trace.get(pid);
+                if (policy == null | pid == -1) {
+                    //                    Integer id = rs.getInt("id");
+                    String persistentId = rs.getString("persistent_id");
+                    int depth = rs.getInt("depth");
+                    String namePath = rs.getString("name_path");
+                    policy = new SecurityRowMappers.PolicyRowMapper()
+                            .mapRow(rs, 0);
+
+                    //todo: put active status here!
+                    trace.put(pid, policy);
+
+                    //fixme: since leaves are mentioned first, maybe retrieve
+                    SortedMap<String, KorAPResource.Container[]> submatch;
+                    if ((submatch = containerMap.getPrefixSubMap(namePath))
+                            == null) {
+
+                        cursor = new KorAPResource.Container[depth + 1];
+                        cursor[depth] = new KorAPResource.Container(
+                                persistentId,
+                                ResourceFactory.getResource(rs.getInt("type"))
+                                        .getClass());
+                        containerMap.put(namePath, cursor);
+                    }else {
+                        KorAPResource.Container[] values = submatch
+                                .get(submatch.firstKey());
+                        values[depth] = new KorAPResource.Container(
+                                persistentId,
+                                ResourceFactory.getResource(rs.getInt("type"))
+                                        .getClass());
+                    }
+                }
+            }
+
+            List<KorAPResource.Container> result = new ArrayList<>();
+            for (KorAPResource.Container[] values : containerMap.values()) {
+                for (KorAPResource.Container container : values)
+                    if (container == null)
+                        containerMap.remove(values);
+                result.add(values[values.length - 1]);
+            }
+            return result;
+        }
+    }
+
+}
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
new file mode 100644
index 0000000..602c496
--- /dev/null
+++ b/src/main/resources/log4j.properties
@@ -0,0 +1,22 @@
+
+# Root logger option
+#log4j.threshold=ALL
+log4j.rootLogger=INFO, stdout, debugLog
+log4j.logger.log=ERROR, errorLog
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd, HH:mm:ss} %C{6} - %M%n %-5p: %m%n
+
+log4j.appender.errorLog=org.apache.log4j.RollingFileAppender
+log4j.appender.errorLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.errorLog.layout.ConversionPattern=%d{MMM dd, yyyy HH:mm:ss} %C{6} - %M %n %-5p: %m%n
+log4j.appender.errorLog.File=./logs/errors.log
+
+
+log4j.appender.debugLog=org.apache.log4j.RollingFileAppender
+log4j.appender.debugLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.debugLog.layout.ConversionPattern=%d{MMM dd, yyyy HH:mm:ss} %C{6} - %M %n %-5p: %m%n
+log4j.appender.debugLog.File=./logs/logging.log
\ No newline at end of file
