/**
   * Method that initializes all vital prerequisites, including POS Tagger
   *
   * @param language Language to be processed with this copy of HeidelTime
   * @param typeToProcess Domain type to be processed
   * @param outputType Output type
   * @param configPath Path to the configuration file for HeidelTimeStandalone
   * @param posTagger POS Tagger to use for preprocessing
   * @param doIntervalTagging Whether or not to invoke the IntervalTagger
   */
  public void initialize(
      Language language,
      DocumentType typeToProcess,
      OutputType outputType,
      String configPath,
      POSTagger posTagger,
      Boolean doIntervalTagging) {
    logger.log(
        Level.INFO, "HeidelTimeStandalone initialized with language " + this.language.getName());

    // set the POS tagger
    this.posTagger = posTagger;

    // set doIntervalTagging flag
    this.doIntervalTagging = doIntervalTagging;

    // read in configuration in case it's not yet initialized
    if (!Config.isInitialized()) {
      if (configPath == null) readConfigFile(CLISwitch.CONFIGFILE.getValue().toString());
      else readConfigFile(configPath);
    }

    try {
      heidelTime = new HeidelTime();
      heidelTime.initialize(
          new UimaContextImpl(language, typeToProcess, CLISwitch.VERBOSITY2.getIsActive()));
      logger.log(Level.INFO, "HeidelTime initialized");
    } catch (Exception e) {
      e.printStackTrace();
      logger.log(Level.WARNING, "HeidelTime could not be initialized");
    }

    // Initialize JCas factory -------------
    logger.log(Level.FINE, "Initializing JCas factory...");
    try {
      TypeSystemDescription[] descriptions =
          new TypeSystemDescription[] {
            UIMAFramework.getXMLParser()
                .parseTypeSystemDescription(
                    new XMLInputSource(
                        this.getClass()
                            .getClassLoader()
                            .getResource(Config.get(Config.TYPESYSTEMHOME))))
          };
      jcasFactory = new JCasFactoryImpl(descriptions);
      logger.log(Level.INFO, "JCas factory initialized");
    } catch (Exception e) {
      e.printStackTrace();
      logger.log(Level.WARNING, "JCas factory could not be initialized");
    }
  }
  /**
   * Processes document with HeidelTime
   *
   * @param document
   * @param documentCreationTime Date when document was created - especially important if document
   *     is of type {@link DocumentType#NEWS}
   * @return Annotated document
   * @throws DocumentCreationTimeMissingException If document creation time is missing when
   *     processing a document of type {@link DocumentType#NEWS}
   */
  public String process(String document, Date documentCreationTime, ResultFormatter resultFormatter)
      throws DocumentCreationTimeMissingException {
    logger.log(Level.INFO, "Processing started");

    // Generate jcas object ----------
    logger.log(Level.FINE, "Generate CAS object");
    JCas jcas = null;
    try {
      jcas = jcasFactory.createJCas();
      jcas.setDocumentText(document);
      logger.log(Level.FINE, "CAS object generated");
    } catch (Exception e) {
      e.printStackTrace();
      logger.log(Level.WARNING, "Cas object could not be generated");
    }

    // Process jcas object -----------
    try {
      logger.log(Level.FINER, "Establishing preconditions...");
      provideDocumentCreationTime(jcas, documentCreationTime);
      establishHeidelTimePreconditions(jcas);
      logger.log(Level.FINER, "Preconditions established");

      heidelTime.process(jcas);

      logger.log(Level.INFO, "Processing finished");
    } catch (Exception e) {
      e.printStackTrace();
      logger.log(Level.WARNING, "Processing aborted due to errors");
    }

    // process interval tagging ---
    if (doIntervalTagging) runIntervalTagger(jcas);

    // Process results ---------------
    logger.log(Level.FINE, "Formatting result...");
    // PrintAnnotations.printAnnotations(jcas.getCas(), System.out);
    String result = null;
    try {
      result = resultFormatter.format(jcas);
      logger.log(Level.INFO, "Result formatted");
    } catch (Exception e) {
      e.printStackTrace();
      logger.log(Level.WARNING, "Result could not be formatted");
    }

    return result;
  }