/**
   * Specifies arguments accepted by all descendants from CommonCoreQueryEvaluator. When overriding
   * this, make sure to call super.setupArguments() and that defaultOptimization is set before you
   * do.
   */
  @Override
  public void setupArguments() {
    super.setupArguments();
    this.args.addEnumOption(
        "optimization",
        "Specify the optimization that should be applied",
        this.defaultOptimization);
    this.args.addEnumOption("join", "Specify the join algorithm to be used", JOIN.DEFAULT);
    this.args.addEnumOption(
        "optional", "Specify the join algorithm to be used in the optional operator", JOIN.DEFAULT);
    this.args.addEnumOption("sort", "Specify the sort algorithm to be used", SORT.DEFAULT);
    this.args.addEnumOption(
        "distinct", "Specify the distinct algorithm to be used", DISTINCT.DEFAULT);
    this.args.addEnumOption("result", "Specify the storage type of the result", QueryResult.type);
    this.args.addEnumOption(
        "codemap",
        "The type of map used for administrating the codes for values.",
        LiteralFactory.MapType.PREFIXCODEMAP);
    this.args.addEnumOption(
        "storage",
        "The type of storage used for all operators, indices and (intermediate) results.",
        STORAGE.MEMORY);
    this.args.addStringOption(
        "tmpdir",
        "The type of storage used for all operators, indices and (intermediate) results. You can also specify several temporary directories (separated by commas) in order to e.g. use several hard disks for performance reasons.",
        "");
    this.args.addEnumOption(
        "merge_join_optional",
        "Specifies if MergeJoinWithoutSorting, MergeJoinSort, MergeWithoutSortingOptional and MergeJoinOptional should be replaced by their parallel versions.",
        MERGE_JOIN_OPTIONAL.SEQUENTIAL);
    this.args.addStringOption(
        "paralleloperands",
        "specifies whether or not ParallelOperands are added as operands of joins in order to compute operand results in parallel. The string option can be \"NONE\" for do not add ParallelOperators, \"N\", where N is a number, which is used as size for the Bounded Queue (the default is used when N<=0), and \"lastN\" if only the last join should get ParallelOperators (N like before). Furthermore, if the the string starts with BLOCK, then the computed operand results are transmitted blockwise to the join/optional operator.",
        "NONE");
    this.args.addIntegerOption(
        "jointhreads",
        "specifies the number of threads to start for the parallel join operators...",
        ParallelJoin.getDEFAULT_NUMBER_THREADS());
    this.args.addIntegerOption(
        "joinbuffer",
        "specifies the maximum size for the buffer for the parallel join operators...",
        ParallelJoin.getMAXBUFFER());
    this.args.addEnumOption(
        "heap", "specifies the heap type to be used", SortConfiguration.getDEFAULT_HEAP_TYPE());
    this.args.addIntegerOption(
        "indexheap",
        "specifies the heap height used for index construction",
        SortConfiguration.getDEFAULT_HEIGHT());
    this.args.addEnumOption(
        "tosort",
        "specifies the tosort type to be used in heaps for the initial runs (if no heaps are used, i.e. tosort!=NONE)",
        SortConfiguration.getDEFAULT_TOSORT());
    this.args.addEnumOption(
        "mergeheaptype",
        "The heap type to be used for merging the initial runs for external merge sort.",
        SortConfiguration.getDEFAULT_MERGEHEAP_TYPE());
    this.args.addIntegerOption(
        "mergeheapheight",
        "The heap size to be used for merging the initial runs for external merge sort.",
        SortConfiguration.getDEFAULT_MERGE_HEAP_HEIGHT());

    this.args.addIntegerOption(
        "mergethreads",
        "specifies the number of threads to start for the merging phase of merge sort (=1 means sequential merging).",
        DBMergeSortedBag.getNumberOfThreads());
    this.args.addStringOption(
        "externalontology",
        "specifies an external ontology, which is used to optimize RDFS inference by replacing triple patterns adressing RDFS triple by concrete ones regarding the external ontology...",
        "");
    this.args.addIntegerOption(
        "chunk",
        "defines the chunk fraction of the data for SortedChunksHeap...",
        SortConfiguration.getDEFAULT_K());
    this.args.addIntegerOption(
        "yagomax",
        "specifies the maximum triples read by the YAGO parser (<=0 for all triples)...",
        YagoParser.getMaxTriples());
    this.args.addBooleanOption(
        "inmemoryexternalontologyinference",
        "specifies if the inference computations in external ontologies are done in memory (or disks are used for temporary data)",
        false);
    this.args.addStringOption(
        "encoding", "specifies the used encoding for reading in data files...", encoding);
  }
  private void init(
      final String type,
      final String externalontology,
      final boolean inmemoryexternalontologyinference,
      final RDFS rdfs,
      final LiteralFactory.MapType codemap,
      final String[] tmpDirs,
      final boolean loadindexinfo,
      final PARALLELOPERANDS parallelOperands,
      final boolean blockwise,
      final int limit,
      final int jointhreads,
      final int joinbuffer,
      final Heap.HEAPTYPE heap,
      final ToSort.TOSORT tosort,
      final int indexheap,
      final int mergeheapheight,
      final Heap.HEAPTYPE mergeheaptype,
      final int chunk,
      final int mergethreads,
      final int yagomax,
      final QueryResult.TYPE resulttype,
      final STORAGE storage,
      final JOIN join,
      final JOIN optional,
      final SORT sort,
      final DISTINCT distinct,
      final MERGE_JOIN_OPTIONAL merge_join_optional,
      final String encoding) {
    this.type = type;
    this.externalontology = externalontology;
    this.inmemoryexternalontologyinference = inmemoryexternalontologyinference;

    this.rdfs = rdfs;
    LiteralFactory.setType(codemap);
    DBMergeSortedBag.setTmpDir(tmpDirs);
    DiskCollection.setTmpDir(tmpDirs);
    if (loadindexinfo) {
      lupos.datastructures.paged_dbbptree.DBBPTree.setTmpDir(tmpDirs[0], !loadindexinfo);
    }

    this.parallelOperands = parallelOperands;
    RuleJoinWithParallelOperands.setBLOCKWISE(blockwise);
    if (parallelOperands == PARALLELOPERANDS.LAST) {
      RuleEngineForParallelOperator.setLastJoin(true);
    } else if (parallelOperands == PARALLELOPERANDS.ALL) {
      RuleEngineForParallelOperator.setLastJoin(false);
    }
    if (limit > 0) {
      ParallelOperand.setQueueLimit(limit);
    }
    ParallelJoin.setDEFAULT_NUMBER_THREADS(jointhreads);
    ParallelJoin.setMAXBUFFER(joinbuffer);

    SortConfiguration.setDEFAULT_HEAP_TYPE(heap);
    SortConfiguration.setDEFAULT_TOSORT(tosort);

    SortConfiguration.setDEFAULT_TOSORT_SIZE(indexheap);
    SortConfiguration.setDEFAULT_HEIGHT(indexheap);

    SortConfiguration.setDEFAULT_MERGE_HEAP_HEIGHT(mergeheapheight);
    SortConfiguration.setDEFAULT_MERGEHEAP_TYPE(mergeheaptype);

    SortConfiguration.setDEFAULT_K(chunk);

    if (mergethreads <= 1) {
      DBMergeSortedBag.setParallelMerging(false);
    } else {
      DBMergeSortedBag.setParallelMerging(true);
      DBMergeSortedBag.setNumberOfThreads(mergethreads);
    }
    Parser.setMaxTriples(yagomax);

    QueryResult.type = resulttype;
    this.storage = storage;

    this.join = join;
    this.optional = optional;
    this.sort = sort;
    this.distinct = distinct;
    this.merge_join_optional = merge_join_optional;
    CommonCoreQueryEvaluator.encoding = encoding;
  }