// Path: src/main/java/de/danielbasedow/prospecter/core/Matcher.java
// public class Matcher {
//     protected final TIntObjectHashMap<BitSet> hits = new TIntObjectHashMap<BitSet>();
//     protected final TIntObjectHashMap<QueryNegativeCounter> negativeHits = new TIntObjectHashMap<QueryNegativeCounter>();
// 
//     protected final QueryManager queryManager;
// 
//     public Matcher(QueryManager qm) {
//         queryManager = qm;
//     }
// 
//     public void addHits(TLongList postings) {
//         postings.forEach(new TLongProcedure() {
//             @Override
//             public boolean execute(long posting) {
//                 addHit(posting);
//                 return true;
//             }
//         });
//     }
// 
//     public void addHit(long posting) {
//         int[] unpacked = QueryPosting.unpack(posting);
//         int queryId = unpacked[QueryPosting.QUERY_ID_INDEX];
// 
//         if (unpacked[QueryPosting.QUERY_NOT_INDEX] == 1) {
//             QueryNegativeCounter counter = negativeHits.get(queryId);
//             if (counter == null) {
//                 counter = new QueryNegativeCounter();
//                 negativeHits.put(queryId, counter);
//             }
//             counter.add(unpacked[QueryPosting.QUERY_BIT_INDEX]);
//         } else {
//             BitSet bits = hits.get(queryId);
//             if (bits == null) {
//                 bits = new BitSet();
//                 hits.put(queryId, bits);
//             }
//             bits.set(unpacked[QueryPosting.QUERY_BIT_INDEX]);
//         }
//     }
// 
//     public int getPositiveMatchCount() {
//         return hits.size();
//     }
// 
//     public int getNegativeMatchCount() {
//         return negativeHits.size();
//     }
// 
//     public List<Integer> getMatchedQueries() {
//         final List<Integer> results = new ArrayList<Integer>();
// 
//         hits.forEachEntry(new TIntObjectProcedure<BitSet>() {
//             @Override
//             public boolean execute(int queryId, BitSet bitSet) {
//                 BitSet mask = queryManager.getMask(queryId);
//                 if (mask != null) {
//                     if (mask.equals(bitSet)) {
//                         results.add(queryId);
//                     } else {
//                         QueryNegativeCounter countMask = queryManager.getQueryNegativeCounter(queryId);
//                         if (countMask != null) {
//                             QueryNegativeCounter actualCount = negativeHits.get(queryId);
//                             if (actualCount == null) {
//                                 actualCount = new QueryNegativeCounter();
//                             }
//                             int[] bitPositions = countMask.getBitPositionsToSet(actualCount);
//                             if (bitPositions.length > 0) {
//                                 for (int position : bitPositions) {
//                                     bitSet.set(position, true);
//                                 }
//                             }
//                             if (mask.equals(bitSet)) {
//                                 results.add(queryId);
//                             }
//                         }
//                     }
//                 }
//                 return true;
//             }
//         });
//         return results;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/Token.java
// public class Token<T> {
//     private final T token;
//     private final MatchCondition condition;
// 
//     public Token(T token) {
//         this(token, MatchCondition.NONE);
//     }
// 
//     public Token(T token, MatchCondition condition) {
//         this.token = token;
//         this.condition = condition;
//     }
// 
//     public T getToken() {
//         return token;
//     }
// 
//     public int hashCode() {
//         return token.hashCode();
//     }
// 
//     public boolean equals(Object compare) {
//         if (compare instanceof Token) {
//             return token.equals(((Token) compare).getToken());
//         }
//         return false;
//     }
// 
//     public MatchCondition getCondition() {
//         return condition;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/document/Field.java
// public class Field {
//     protected final String name;
//     protected final List<Token> tokens;
// 
//     /**
//      * @param name   name of the field
//      * @param tokens List of tokens in the field
//      */
//     public Field(String name, List<Token> tokens) {
//         this.name = name;
//         this.tokens = tokens;
//     }
// 
//     public List<Token> getTokens() {
//         return tokens;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
// }


import de.danielbasedow.prospecter.core.Matcher;
import de.danielbasedow.prospecter.core.Token;
import de.danielbasedow.prospecter.core.document.Field;
import gnu.trove.list.TLongList;
import gnu.trove.list.array.TLongArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.ConcurrentSkipListMap;
    }

    protected void collectGreaterThanMatches(Matcher matcher, T token) {
        /**
         * The indexGreaterThan contains postings for "field > x" so if x is 10 a posting would be added for 10
         * in order to get the relevant postings we have to look at all key that are LESS than the field value
         * A field containing y has to return all fields less than y so: -n < 0 < x < y < n
         */
        Map<T, TLongList> navigableMap = indexGreaterThan.headMap(token);
        if (navigableMap.size() > 0) {
            for (Map.Entry<T, TLongList> entry : navigableMap.entrySet()) {
                matcher.addHits(entry.getValue());
            }
        }
    }

    protected void collectLessThanMatches(Matcher matcher, T token) {
        /**
         * The indexLessThan contains postings for "field < x" so if x is 10 a posting would be added for 10
         * in order to get the relevant postings we have to look at all key that are GREATER than the field value
         * A field containing y has to return all fields greater than y so: -n < 0 < x < y < n
         */
        Map<T, TLongList> navigableMap = indexLessThan.tailMap(token);
        if (navigableMap.size() > 0) {
            for (Map.Entry<T, TLongList> entry : navigableMap.entrySet()) {
                matcher.addHits(entry.getValue());
            }
        }
    }

// Path: src/main/java/de/danielbasedow/prospecter/core/Matcher.java
// public class Matcher {
//     protected final TIntObjectHashMap<BitSet> hits = new TIntObjectHashMap<BitSet>();
//     protected final TIntObjectHashMap<QueryNegativeCounter> negativeHits = new TIntObjectHashMap<QueryNegativeCounter>();
// 
//     protected final QueryManager queryManager;
// 
//     public Matcher(QueryManager qm) {
//         queryManager = qm;
//     }
// 
//     public void addHits(TLongList postings) {
//         postings.forEach(new TLongProcedure() {
//             @Override
//             public boolean execute(long posting) {
//                 addHit(posting);
//                 return true;
//             }
//         });
//     }
// 
//     public void addHit(long posting) {
//         int[] unpacked = QueryPosting.unpack(posting);
//         int queryId = unpacked[QueryPosting.QUERY_ID_INDEX];
// 
//         if (unpacked[QueryPosting.QUERY_NOT_INDEX] == 1) {
//             QueryNegativeCounter counter = negativeHits.get(queryId);
//             if (counter == null) {
//                 counter = new QueryNegativeCounter();
//                 negativeHits.put(queryId, counter);
//             }
//             counter.add(unpacked[QueryPosting.QUERY_BIT_INDEX]);
//         } else {
//             BitSet bits = hits.get(queryId);
//             if (bits == null) {
//                 bits = new BitSet();
//                 hits.put(queryId, bits);
//             }
//             bits.set(unpacked[QueryPosting.QUERY_BIT_INDEX]);
//         }
//     }
// 
//     public int getPositiveMatchCount() {
//         return hits.size();
//     }
// 
//     public int getNegativeMatchCount() {
//         return negativeHits.size();
//     }
// 
//     public List<Integer> getMatchedQueries() {
//         final List<Integer> results = new ArrayList<Integer>();
// 
//         hits.forEachEntry(new TIntObjectProcedure<BitSet>() {
//             @Override
//             public boolean execute(int queryId, BitSet bitSet) {
//                 BitSet mask = queryManager.getMask(queryId);
//                 if (mask != null) {
//                     if (mask.equals(bitSet)) {
//                         results.add(queryId);
//                     } else {
//                         QueryNegativeCounter countMask = queryManager.getQueryNegativeCounter(queryId);
//                         if (countMask != null) {
//                             QueryNegativeCounter actualCount = negativeHits.get(queryId);
//                             if (actualCount == null) {
//                                 actualCount = new QueryNegativeCounter();
//                             }
//                             int[] bitPositions = countMask.getBitPositionsToSet(actualCount);
//                             if (bitPositions.length > 0) {
//                                 for (int position : bitPositions) {
//                                     bitSet.set(position, true);
//                                 }
//                             }
//                             if (mask.equals(bitSet)) {
//                                 results.add(queryId);
//                             }
//                         }
//                     }
//                 }
//                 return true;
//             }
//         });
//         return results;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/Token.java
// public class Token<T> {
//     private final T token;
//     private final MatchCondition condition;
// 
//     public Token(T token) {
//         this(token, MatchCondition.NONE);
//     }
// 
//     public Token(T token, MatchCondition condition) {
//         this.token = token;
//         this.condition = condition;
//     }
// 
//     public T getToken() {
//         return token;
//     }
// 
//     public int hashCode() {
//         return token.hashCode();
//     }
// 
//     public boolean equals(Object compare) {
//         if (compare instanceof Token) {
//             return token.equals(((Token) compare).getToken());
//         }
//         return false;
//     }
// 
//     public MatchCondition getCondition() {
//         return condition;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/document/Field.java
// public class Field {
//     protected final String name;
//     protected final List<Token> tokens;
// 
//     /**
//      * @param name   name of the field
//      * @param tokens List of tokens in the field
//      */
//     public Field(String name, List<Token> tokens) {
//         this.name = name;
//         this.tokens = tokens;
//     }
// 
//     public List<Token> getTokens() {
//         return tokens;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
// }


// Path: src/main/java/de/danielbasedow/prospecter/core/index/RangeIndex.java
import de.danielbasedow.prospecter.core.Matcher;
import de.danielbasedow.prospecter.core.Token;
import de.danielbasedow.prospecter.core.document.Field;
import gnu.trove.list.TLongList;
import gnu.trove.list.array.TLongArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.ConcurrentSkipListMap;

    }

    protected void collectGreaterThanMatches(Matcher matcher, T token) {
        /**
         * The indexGreaterThan contains postings for "field > x" so if x is 10 a posting would be added for 10
         * in order to get the relevant postings we have to look at all key that are LESS than the field value
         * A field containing y has to return all fields less than y so: -n < 0 < x < y < n
         */
        Map<T, TLongList> navigableMap = indexGreaterThan.headMap(token);
        if (navigableMap.size() > 0) {
            for (Map.Entry<T, TLongList> entry : navigableMap.entrySet()) {
                matcher.addHits(entry.getValue());
            }
        }
    }

    protected void collectLessThanMatches(Matcher matcher, T token) {
        /**
         * The indexLessThan contains postings for "field < x" so if x is 10 a posting would be added for 10
         * in order to get the relevant postings we have to look at all key that are GREATER than the field value
         * A field containing y has to return all fields greater than y so: -n < 0 < x < y < n
         */
        Map<T, TLongList> navigableMap = indexLessThan.tailMap(token);
        if (navigableMap.size() > 0) {
            for (Map.Entry<T, TLongList> entry : navigableMap.entrySet()) {
                matcher.addHits(entry.getValue());
            }
        }
    }

    public void addPosting(Token token, Long posting) {