diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder.java
deleted file mode 100644
index 96b94a0..0000000
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder.java
+++ /dev/null
@@ -1,318 +0,0 @@
-package de.ids_mannheim.korap.query.serialize;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-
-import de.ids_mannheim.korap.resource.Relation;
-import de.ids_mannheim.korap.utils.JsonUtils;
-
-import java.io.IOException;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author hanl
- * @date 06/12/2013
- */
-@Deprecated
-public class CollectionQueryBuilder {
-
-    private CollectionTypes types;
-    private List<Map> rq;
-    private Multimap<String, String> mfilter;
-    private Multimap<String, String> mextension;
-    private Relation simpleFilterRel = Relation.AND;
-    private Relation simpleExtendRel = Relation.AND;
-
-
-    public CollectionQueryBuilder() {
-        this.rq = new ArrayList<>();
-        this.mfilter = ArrayListMultimap.create();
-        this.mextension = ArrayListMultimap.create();
-        this.types = new CollectionTypes();
-    }
-
-    public CollectionQueryBuilder addResource(String query) {
-        try {
-            List v = JsonUtils.read(query, LinkedList.class);
-            this.rq.addAll(v);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Conversion went wrong!");
-        }
-        return this;
-    }
-
-    public CollectionQueryBuilder addResources(List<String> queries) {
-        for (String query : queries)
-            addResource(query);
-        return this;
-    }
-
-    public CollectionQueryBuilder addMetaFilter(String key, String value) {
-        this.mfilter.put(key, value);
-        return this;
-    }
-
-
-    public CollectionQueryBuilder addMetaFilterQuery(String queries) {
-        this.mfilter.putAll(resRel(queries));
-        return this;
-    }
-
-    public CollectionQueryBuilder addMetaExtend(String key, String value) {
-        this.mextension.put(key, value);
-        return this;
-    }
-
-
-    public CollectionQueryBuilder setFilterAttributeRelation(Relation rel) {
-        simpleFilterRel = rel;
-        return this;
-    }
-
-
-    public CollectionQueryBuilder setExtendAttributeRelation(Relation rel) {
-        simpleExtendRel = rel;
-        return this;
-    }
-
-    public CollectionQueryBuilder addMetaExtendQuery(String queries) {
-        this.mextension.putAll(resRel(queries));
-        return this;
-    }
-
-
-    @Deprecated
-    private List<Map> createFilter(Relation rel) {
-        String relation = rel == Relation.AND ? "and" : "or";
-        List<Map> mfil = new ArrayList();
-        boolean multypes = this.mfilter.keySet().size() > 1;
-        String def_key = null;
-
-        if (!multypes) {
-            Multiset<String> keys = this.mfilter.keys();
-            def_key = keys.toArray(new String[keys.size()])[0];
-        }
-
-        List value = this.createValue(this.mfilter);
-
-        if (mfilter.values().size() == 1)
-            Collections.addAll(mfil, types.createMetaFilter((Map) value.get(0)));
-        else {
-            Map group;
-            if (!multypes)
-                group = types.createGroup(relation, def_key, value);
-            else
-                group = types.createGroup(relation, null, value);
-            Collections.addAll(mfil, types.createMetaFilter(group));
-        }
-        return mfil;
-    }
-
-    @Deprecated
-    private List<Map> createExtender(Relation rel) {
-        String relation = rel == Relation.AND ? "and" : "or";
-        List<Map> mex = new ArrayList();
-        boolean multypes = this.mextension.keys().size() > 1;
-        String def_key = null;
-
-        if (!multypes)
-            def_key = this.mextension.keys().toArray(new String[0])[0];
-
-        List value = this.createValue(this.mextension);
-        // todo: missing: - takes only one resource, but resources can be chained!
-        if (this.mextension.values().size() == 1)
-            Collections.addAll(mex, types.createMetaExtend((Map) value.get(0)));
-        else {
-            Map group;
-            if (!multypes)
-                group = types.createGroup(relation, def_key, value);
-            else
-                group = types.createGroup(relation, null, value);
-            Collections.addAll(mex, types.createMetaExtend(group));
-        }
-        return mex;
-    }
-
-    private List<Map> join() {
-        List<Map> cursor = new ArrayList<>(this.rq);
-        if (!this.mfilter.isEmpty())
-            cursor.addAll(this.createFilter(simpleFilterRel));
-        if (!this.mextension.isEmpty())
-            cursor.addAll(this.createExtender(simpleExtendRel));
-        return cursor;
-    }
-
-    private List createValue(Multimap<String, String> map) {
-        List value = new ArrayList<>();
-        String[] dates = new String[3];
-        for (String key : map.keySet()) {
-            if (key.equals("pubDate")) {
-                dates = processDates((List<String>) map.get(key));
-                continue;
-            }
-
-            if (map.get(key).size() == 1) {
-                Map term = types.createTerm(key, null,
-                        map.get(key).toArray(new String[0])[0], null);
-                value.add(term);
-            } else {
-                boolean multypes = map.keySet().size() > 1;
-                List g = new ArrayList();
-                for (String v : map.get(key))
-                    g.add(types.createTerm(null, v, null));
-
-                if (multypes) {
-                    Map group = types.createGroup("and", key, g);
-                    value.add(group);
-                } else
-                    value.addAll(g);
-
-            }
-        }
-
-        int idx = 3;
-        if (dates[0] != null && dates[0].equals("r")) {
-            Map term1 = types.createTerm(null, dates[1], "korap:date");
-            Map term2 = types.createTerm(null, dates[2], "korap:date");
-            Map group = types.createGroup("between", "pubDate", Arrays.asList(term1, term2));
-            value.add(group);
-        } else if (dates[1] != null) {
-            Map term1 = types.createTerm(null, dates[1], "korap:date");
-            Map group = types.createGroup("since", "pubDate", Arrays.asList(term1));
-            value.add(group);
-        } else if (dates[2] != null) {
-            Map term1 = types.createTerm(null, dates[2], "korap:date");
-            Map group = types.createGroup("until", "pubDate", Arrays.asList(term1));
-            value.add(group);
-        }
-
-        for (int i = idx; i < dates.length; i++) {
-            if (dates[i] != null) {
-                Map term1 = types.createTerm(dates[i], "korap:date");
-                Map group = types.createGroup("exact", "pubDate", Arrays.asList(term1));
-                value.add(group);
-            }
-        }
-        return value;
-    }
-
-    private String[] processDates(List<String> dates) {
-        if (dates.isEmpty())
-            return new String[3];
-        String[] el = new String[dates.size() + 3];
-        int idx = 3;
-        for (String value : dates) {
-            if (value.contains("<")) {
-                String[] sp = value.split("<");
-                el[1] = sp[1];
-            } else if (value.contains(">")) {
-                String[] sp = value.split(">");
-                el[2] = sp[1];
-            } else {
-                el[idx] = value;
-                idx++;
-            }
-        }
-        if (el[1] != null && el[2] != null)
-            el[0] = "r";
-        return el;
-    }
-
-    public List<Map> raw() {
-        return join();
-    }
-
-    public String toCollections() {
-        Map meta = new LinkedHashMap();
-        meta.put("collections", join());
-        return JsonUtils.toJSON(meta);
-    }
-
-    /**
-     * returns all references to parents and meta query as string representation
-     *
-     * @return
-     */
-    public JsonNode toNode() {
-        return JsonUtils.valueToTree(join());
-    }
-
-    public String toJSON() {
-        return JsonUtils.toJSON(join());
-    }
-
-
-    /**
-     * resolves all queries as equal (hierarchy) AND/OR relations
-     * grouping is not supported!
-     *
-     * @param queries
-     * @return
-     */
-    private Multimap<String, String> resRel(String queries) {
-        Multimap<String, String> qmap = ArrayListMultimap.create();
-        String op = null;
-        if (queries.contains("AND") | queries.contains("OR"))
-            op = queries.contains("AND") ? "AND" : "OR";
-        else if (queries.contains("&") | queries.contains("|"))
-            op = queries.contains("&") ? "&" : "|";
-
-        if (op == null)
-            return qmap;
-
-        String[] spl = queries.trim().split(op);
-        for (String query : spl) {
-            String[] q = query.split("=");
-            if (q.length > 1) {
-                String attr = q[0].trim();
-                String val = q[1].trim();
-                qmap.put(attr, val);
-            }
-            // todo: return error when query not well-formed
-        }
-        return qmap;
-    }
-
-    /**
-     * resolve relations and allow grouping of attributes: (tc1 and tc1) or (tc3)
-     *
-     * @param queries
-     * @param filter  flag if either filter or extend collection
-     * @return
-     */
-    private void resRelation(String queries, boolean filter) {
-        Pattern p = Pattern.compile("\\(([\\w\\s:]+)\\)");
-        List _fill = new ArrayList();
-        Matcher m = p.matcher(queries);
-        while (m.find()) {
-            String gr = m.group(1);
-            _fill.add(gr);
-            String whole = "(" + gr + ")";
-            int fin = queries.lastIndexOf(whole);
-            String sub = queries.substring(queries.indexOf(whole), queries.lastIndexOf(whole));
-            queries.replace(whole, "");
-        }
-    }
-
-    private void v(String queries, boolean filter) {
-        // and exclude sub-groups?? : ((tc=121))
-        Pattern p = Pattern.compile("\\(([\\w\\s=]+)\\)");
-        List _fill = new ArrayList();
-        Matcher m = p.matcher(queries);
-        while (m.find()) {
-            String gr = m.group(1);
-
-        }
-
-    }
-
-    public void clear() {
-        this.rq.clear();
-        this.mfilter.clear();
-        this.mextension.clear();
-    }
-}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
deleted file mode 100644
index 3d62b52..0000000
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder2.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package de.ids_mannheim.korap.query.serialize;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import de.ids_mannheim.korap.utils.JsonUtils;
-
-import java.io.IOException;
-import java.util.*;
-
-/**
- * @author hanl
- * @date 13/05/2014
- */
-public class CollectionQueryBuilder2 {
-
-    private List<Map> rq;
-    private Map groups;
-    private CollectionTypes types;
-    private boolean verbose;
-
-    public CollectionQueryBuilder2() {
-        this.verbose = false;
-        this.rq = new ArrayList<>();
-        this.groups = new HashMap();
-        this.types = new CollectionTypes();
-    }
-
-    public CollectionQueryBuilder2(boolean verbose) {
-        this();
-        this.verbose = verbose;
-    }
-
-
-    public CollectionQueryBuilder2 addResource(String collections) {
-        try {
-            List v = JsonUtils.read(collections, LinkedList.class);
-            this.rq.addAll(v);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Conversion went wrong!");
-        }
-        return this;
-    }
-
-    public CollectionQueryBuilder2 addResources(List<String> queries) {
-        for (String query : queries)
-            addResource(query);
-        return this;
-    }
-
-    public CollectionQueryBuilder2 setQuery(String query) {
-        CollectionQueryProcessor tree = new CollectionQueryProcessor();
-        tree.process(query);
-        this.groups = tree.getRequestMap();
-        return this;
-    }
-
-    public List raw() {
-        List list = new ArrayList(this.rq);
-        list.add(types.createMetaFilter(this.groups));
-        return list;
-    }
-
-    private Object raw2() {
-        return this.groups;
-    }
-
-    public String toCollections() {
-        Map value = new HashMap();
-        value.put("collections", raw2());
-        return JsonUtils.toJSON(value);
-    }
-
-    public JsonNode toNode() {
-        return JsonUtils.valueToTree(raw2());
-    }
-
-    public String toJSON() {
-        return JsonUtils.toJSON(raw2());
-    }
-
-
-    // add public filter to original query
-    private void addToGroup() {
-        Map first = this.rq.get(0);
-
-    }
-}
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java b/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
deleted file mode 100644
index 285f14b..0000000
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/CollectionQueryBuilder3.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package de.ids_mannheim.korap.query.serialize;
-
-import de.ids_mannheim.korap.utils.JsonUtils;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * convenience builder class for collection query -- new one
- *
- * @author hanl
- * @date 16/09/2014
- */
-public class CollectionQueryBuilder3 {
-
-    private boolean verbose;
-    private List<Map> rq;
-    private StringBuilder builder;
-
-    public CollectionQueryBuilder3() {
-        this(false);
-    }
-
-    public CollectionQueryBuilder3(boolean verbose) {
-        this.verbose = verbose;
-        this.builder = new StringBuilder();
-        this.rq = new LinkedList<>();
-    }
-
-
-    public CollectionQueryBuilder3 addSegment(String field, String value) {
-        String f = field + "=" + value;
-        this.builder.append(f);
-        return this;
-    }
-
-    public CollectionQueryBuilder3 add(String query) {
-        this.builder.append(query);
-        return this;
-    }
-
-    public CollectionQueryBuilder3 and() {
-        this.builder.append(" & ");
-        return this;
-    }
-
-    public CollectionQueryBuilder3 or() {
-        this.builder.append(" | ");
-        return this;
-    }
-
-    public CollectionQueryBuilder3 addResource(String collection) {
-        try {
-            List v = JsonUtils.read(collection, LinkedList.class);
-            this.rq.addAll(v);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Conversion went wrong!");
-        }
-        return this;
-    }
-
-    public List getRequest() {
-        List list = new ArrayList();
-        if (!this.rq.isEmpty())
-            list.addAll(this.rq);
-        System.out.println("RAW QUERY " + this.builder.toString());
-        CollectionQueryProcessor tree = new CollectionQueryProcessor(this.verbose);
-        tree.process(this.builder.toString());
-        list.add(tree.getRequestMap());
-        return list;
-    }
-
-    public String toJSON() {
-        return JsonUtils.toJSON(getRequest());
-    }
-
-
-}
