// Path: src/main/java/de/danielbasedow/prospecter/core/analysis/Analyzer.java
// public interface Analyzer {
//     /**
//      * Tokenizes raw input
//      *
//      * @param input raw String that should be turned into tokens
//      * @return list of tokens
//      * @throws TokenizerException
//      */
//     public List<Token> tokenize(String input) throws TokenizerException;
// 
//     /**
//      * Tokenizes raw input. It is possible to turn off generating formerly unknown tokens. This makes sense when
//      * tokenizing documents, as any token in a document has to have been already seen in a query to have any chance
//      * of matching.
//      *
//      * @param input              raw String that should be turned into tokens
//      * @param dontGenerateNewIds if set to true no new tokens will be generated.
//      * @return list of tokens
//      * @throws TokenizerException
//      */
//     public List<Token> tokenize(String input, boolean dontGenerateNewIds) throws TokenizerException;
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/persistence/DummyQueryStorage.java
// public class DummyQueryStorage implements QueryStorage {
//     @Override
//     public void addQuery(Integer queryId, String json) {
//     }
// 
//     @Override
//     public Set<Map.Entry<Integer, String>> getAllQueries() {
//         return new HashSet<Map.Entry<Integer, String>>();
//     }
// 
//     @Override
//     public void deleteQuery(Integer queryId) {
//     }
// 
//     @Override
//     public void close() {
//     }
// 
//     @Override
//     public String getRawQuery(Integer queryId) {
//         return null;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/persistence/MapDBStore.java
// public class MapDBStore implements QueryStorage {
//     private static final Logger LOGGER = LoggerFactory.getLogger(MapDBStore.class);
// 
//     private static final int DEFAULT_UNWRITTEN_CHANGES_LIMIT = 10000;
//     private final DB database;
//     private final HTreeMap<Integer, String> map;
//     private int unwrittenChangesCount;
//     private final int unwrittenChangesLimit;
//     private final String name;
// 
//     public MapDBStore(File file) {
//         name = file.getName();
//         LOGGER.debug("opening query store " + name);
//         database = DBMaker.newFileDB(file).make();
//         LOGGER.debug("reading query store " + name);
//         map = database.getHashMap("queries");
//         unwrittenChangesCount = 0;
//         unwrittenChangesLimit = DEFAULT_UNWRITTEN_CHANGES_LIMIT;
//     }
// 
//     @Override
//     public void addQuery(Integer queryId, String json) {
//         map.put(queryId, json);
//         commitIfNecessary();
//     }
// 
//     private void commitIfNecessary() {
//         unwrittenChangesCount++;
//         if (unwrittenChangesCount >= unwrittenChangesLimit) {
//             LOGGER.debug("committing changes in query store (auto-commit limit reached)");
//             unwrittenChangesCount = 0;
//             database.commit();
//         }
//     }
// 
//     public void deleteQuery(Integer queryId) {
//         map.remove(queryId);
//         commitIfNecessary();
//     }
// 
//     @Override
//     public Set<Map.Entry<Integer, String>> getAllQueries() {
//         return map.entrySet();
//     }
// 
//     @Override
//     public void close() {
//         LOGGER.debug("closing query store: " + name);
//         database.commit();
//         database.close();
//     }
// 
//     @Override
//     public String getRawQuery(Integer queryId) {
//         return map.get(queryId);
//     }
// }


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
import de.danielbasedow.prospecter.core.analysis.Analyzer;
import de.danielbasedow.prospecter.core.index.*;
import de.danielbasedow.prospecter.core.persistence.DummyQueryStorage;
import de.danielbasedow.prospecter.core.persistence.MapDBStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Map;
    }

    private void parseJSON() throws SchemaConfigurationError {
        try {
            ObjectNode fields = (ObjectNode) root.get("fields");
            Iterator<Map.Entry<String, JsonNode>> iterator = fields.fields();
            while (iterator.hasNext()) {
                Map.Entry<String, JsonNode> entry = iterator.next();
                FieldIndex index = buildField(entry.getKey(), entry.getValue());
                schema.addFieldIndex(index.getName(), index);
            }
            JsonNode persistence = root.get("persistence");
            //as a default set DummyQueryStorage. Only if persistence options are provided overwrite it
            schema.setQueryStorage(new DummyQueryStorage());
            if (persistence != null && persistence.getNodeType() == JsonNodeType.OBJECT) {
                //if persistence key doesn't exist there is no persistence
                JsonNode file = persistence.get("file");
                if (file != null && file.getNodeType() == JsonNodeType.STRING) {
                    schema.setQueryStorage(new MapDBStore(new File(schemaDirectory, file.asText())));
                } else {
                    LOGGER.error("unable to get file name for query storage. Continuing with no persistence!");
                }
            }
        } catch (Exception e) {
            throw new SchemaConfigurationError("Could not parse JSON tree", e);
        }
        schema.init();
    }

    protected FieldIndex buildField(String fieldName, JsonNode node) throws SchemaConfigurationError {
// Path: src/main/java/de/danielbasedow/prospecter/core/analysis/Analyzer.java
// public interface Analyzer {
//     /**
//      * Tokenizes raw input
//      *
//      * @param input raw String that should be turned into tokens
//      * @return list of tokens
//      * @throws TokenizerException
//      */
//     public List<Token> tokenize(String input) throws TokenizerException;
// 
//     /**
//      * Tokenizes raw input. It is possible to turn off generating formerly unknown tokens. This makes sense when
//      * tokenizing documents, as any token in a document has to have been already seen in a query to have any chance
//      * of matching.
//      *
//      * @param input              raw String that should be turned into tokens
//      * @param dontGenerateNewIds if set to true no new tokens will be generated.
//      * @return list of tokens
//      * @throws TokenizerException
//      */
//     public List<Token> tokenize(String input, boolean dontGenerateNewIds) throws TokenizerException;
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/persistence/DummyQueryStorage.java
// public class DummyQueryStorage implements QueryStorage {
//     @Override
//     public void addQuery(Integer queryId, String json) {
//     }
// 
//     @Override
//     public Set<Map.Entry<Integer, String>> getAllQueries() {
//         return new HashSet<Map.Entry<Integer, String>>();
//     }
// 
//     @Override
//     public void deleteQuery(Integer queryId) {
//     }
// 
//     @Override
//     public void close() {
//     }
// 
//     @Override
//     public String getRawQuery(Integer queryId) {
//         return null;
//     }
// }
// 
// Path: src/main/java/de/danielbasedow/prospecter/core/persistence/MapDBStore.java
// public class MapDBStore implements QueryStorage {
//     private static final Logger LOGGER = LoggerFactory.getLogger(MapDBStore.class);
// 
//     private static final int DEFAULT_UNWRITTEN_CHANGES_LIMIT = 10000;
//     private final DB database;
//     private final HTreeMap<Integer, String> map;
//     private int unwrittenChangesCount;
//     private final int unwrittenChangesLimit;
//     private final String name;
// 
//     public MapDBStore(File file) {
//         name = file.getName();
//         LOGGER.debug("opening query store " + name);
//         database = DBMaker.newFileDB(file).make();
//         LOGGER.debug("reading query store " + name);
//         map = database.getHashMap("queries");
//         unwrittenChangesCount = 0;
//         unwrittenChangesLimit = DEFAULT_UNWRITTEN_CHANGES_LIMIT;
//     }
// 
//     @Override
//     public void addQuery(Integer queryId, String json) {
//         map.put(queryId, json);
//         commitIfNecessary();
//     }
// 
//     private void commitIfNecessary() {
//         unwrittenChangesCount++;
//         if (unwrittenChangesCount >= unwrittenChangesLimit) {
//             LOGGER.debug("committing changes in query store (auto-commit limit reached)");
//             unwrittenChangesCount = 0;
//             database.commit();
//         }
//     }
// 
//     public void deleteQuery(Integer queryId) {
//         map.remove(queryId);
//         commitIfNecessary();
//     }
// 
//     @Override
//     public Set<Map.Entry<Integer, String>> getAllQueries() {
//         return map.entrySet();
//     }
// 
//     @Override
//     public void close() {
//         LOGGER.debug("closing query store: " + name);
//         database.commit();
//         database.close();
//     }
// 
//     @Override
//     public String getRawQuery(Integer queryId) {
//         return map.get(queryId);
//     }
// }


// Path: src/main/java/de/danielbasedow/prospecter/core/schema/SchemaBuilderJSON.java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
import de.danielbasedow.prospecter.core.analysis.Analyzer;
import de.danielbasedow.prospecter.core.index.*;
import de.danielbasedow.prospecter.core.persistence.DummyQueryStorage;
import de.danielbasedow.prospecter.core.persistence.MapDBStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Map;

    }

    private void parseJSON() throws SchemaConfigurationError {
        try {
            ObjectNode fields = (ObjectNode) root.get("fields");
            Iterator<Map.Entry<String, JsonNode>> iterator = fields.fields();
            while (iterator.hasNext()) {
                Map.Entry<String, JsonNode> entry = iterator.next();
                FieldIndex index = buildField(entry.getKey(), entry.getValue());
                schema.addFieldIndex(index.getName(), index);
            }
            JsonNode persistence = root.get("persistence");
            //as a default set DummyQueryStorage. Only if persistence options are provided overwrite it
            schema.setQueryStorage(new DummyQueryStorage());
            if (persistence != null && persistence.getNodeType() == JsonNodeType.OBJECT) {
                //if persistence key doesn't exist there is no persistence
                JsonNode file = persistence.get("file");
                if (file != null && file.getNodeType() == JsonNodeType.STRING) {
                    schema.setQueryStorage(new MapDBStore(new File(schemaDirectory, file.asText())));
                } else {
                    LOGGER.error("unable to get file name for query storage. Continuing with no persistence!");
                }
            }
        } catch (Exception e) {
            throw new SchemaConfigurationError("Could not parse JSON tree", e);
        }
        schema.init();
    }

    protected FieldIndex buildField(String fieldName, JsonNode node) throws SchemaConfigurationError {
        FieldIndex index = null;