<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>CodecCollector.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">MTAS</a> &gt; <a href="index.source.html" class="el_package">mtas.codec.util</a> &gt; <span class="el_source">CodecCollector.java</span></div><h1>CodecCollector.java</h1><pre class="source lang-java linenums">package mtas.codec.util;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.regex.Pattern;

import mtas.analysis.token.MtasToken;
import mtas.analysis.token.MtasTokenString;
import mtas.codec.MtasCodecPostingsFormat;
import mtas.codec.tree.IntervalTreeNodeData;
import mtas.codec.util.CodecComponent.ComponentDocument;
import mtas.codec.util.CodecComponent.ComponentFacet;
import mtas.codec.util.CodecComponent.ComponentField;
import mtas.codec.util.CodecComponent.ComponentGroup;
import mtas.codec.util.CodecComponent.ComponentCollection;
import mtas.codec.util.CodecComponent.ComponentKwic;
import mtas.codec.util.CodecComponent.ComponentList;
import mtas.codec.util.CodecComponent.ComponentPosition;
import mtas.codec.util.CodecComponent.ComponentSpan;
import mtas.codec.util.CodecComponent.ComponentTermVector;
import mtas.codec.util.CodecComponent.ComponentToken;
import mtas.codec.util.CodecComponent.GroupHit;
import mtas.codec.util.CodecComponent.KwicHit;
import mtas.codec.util.CodecComponent.KwicToken;
import mtas.codec.util.CodecComponent.ListHit;
import mtas.codec.util.CodecComponent.ListToken;
import mtas.codec.util.CodecComponent.Match;
import mtas.codec.util.CodecComponent.SubComponentFunction;
import mtas.codec.util.CodecInfo.IndexDoc;
import mtas.codec.util.CodecSearchTree.MtasTreeHit;
import mtas.codec.util.collector.MtasDataCollector;
import mtas.parser.function.ParseException;
import mtas.parser.function.util.MtasFunctionParserFunction;
import mtas.search.spans.MtasSpanAndQuery;
import mtas.search.spans.MtasSpanMatchAllQuery;
import mtas.search.spans.MtasSpanSequenceItem;
import mtas.search.spans.MtasSpanSequenceQuery;
import mtas.search.spans.MtasSpanTermQuery;
import mtas.search.spans.util.MtasSpanQuery;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.FieldInfos;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.spans.SpanWeight;
import org.apache.lucene.search.spans.Spans;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LegacyNumericUtils;
import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.ByteRunAutomaton;
import org.apache.lucene.util.automaton.CompiledAutomaton;
import org.apache.lucene.util.automaton.RegExp;

/**
 * The Class CodecCollector.
 */
public class CodecCollector {

  /** The Constant log. */
<span class="fc" id="L87">  private static final Log log = LogFactory.getLog(CodecCollector.class);</span>

  /**
   * Instantiates a new codec collector.
   */
<span class="nc" id="L92">  private CodecCollector() {</span>
    // don't do anything
<span class="nc" id="L94">  }</span>

  /**
   * Collect field.
   *
   * @param field the field
   * @param searcher the searcher
   * @param reader the reader
   * @param rawReader the raw reader
   * @param fullDocList the full doc list
   * @param fullDocSet the full doc set
   * @param fieldInfo the field info
   * @param spansQueryWeight the spans query weight
   * @throws IllegalAccessException the illegal access exception
   * @throws IllegalArgumentException the illegal argument exception
   * @throws InvocationTargetException the invocation target exception
   * @throws IOException Signals that an I/O exception has occurred.
   */
  public static void collectField(String field, IndexSearcher searcher,
      IndexReader reader, IndexReader rawReader, List&lt;Integer&gt; fullDocList,
      List&lt;Integer&gt; fullDocSet, ComponentField fieldInfo,
      Map&lt;MtasSpanQuery, SpanWeight&gt; spansQueryWeight)
      throws IllegalAccessException, IllegalArgumentException,
      InvocationTargetException, IOException {

<span class="fc" id="L119">    Map&lt;Integer, List&lt;Integer&gt;&gt; docSets = new HashMap&lt;&gt;();</span>

<span class="fc" id="L121">    ListIterator&lt;LeafReaderContext&gt; iterator = reader.leaves().listIterator();</span>
<span class="fc bfc" id="L122" title="All 2 branches covered.">    while (iterator.hasNext()) {</span>
<span class="fc" id="L123">      LeafReaderContext lrc = iterator.next();</span>
<span class="fc" id="L124">      LeafReader r = lrc.reader();</span>

      // compute relevant docSet/docList
<span class="fc" id="L127">      List&lt;Integer&gt; docSet = null;</span>
<span class="fc" id="L128">      List&lt;Integer&gt; docList = null;</span>
<span class="fc bfc" id="L129" title="All 2 branches covered.">      if (fullDocSet != null) {</span>
<span class="fc" id="L130">        docSet = new ArrayList&lt;&gt;();</span>
<span class="fc" id="L131">        docSets.put(lrc.ord, docSet);</span>
<span class="fc" id="L132">        Iterator&lt;Integer&gt; docSetIterator = fullDocSet.iterator();</span>
<span class="fc" id="L133">        Integer docSetId = null;</span>
<span class="fc" id="L134">        Bits liveDocs = lrc.reader().getLiveDocs();</span>
<span class="fc bfc" id="L135" title="All 2 branches covered.">        while (docSetIterator.hasNext()) {</span>
<span class="fc" id="L136">          docSetId = docSetIterator.next();</span>
          // just to make sure to ignore deleted documents
<span class="fc bfc" id="L138" title="All 2 branches covered.">          if ((docSetId &gt;= lrc.docBase)</span>
<span class="fc bfc" id="L139" title="All 4 branches covered.">              &amp;&amp; (docSetId &lt; lrc.docBase + lrc.reader().maxDoc())</span>
<span class="pc bpc" id="L140" title="1 of 2 branches missed.">              &amp;&amp; (liveDocs == null || liveDocs.get((docSetId - lrc.docBase)))) {</span>
<span class="fc" id="L141">            docSet.add(docSetId);</span>
          }
        }
<span class="fc" id="L144">        Collections.sort(docSet);</span>
      }
<span class="pc bpc" id="L146" title="1 of 2 branches missed.">      if (fullDocList != null) {</span>
<span class="fc" id="L147">        docList = new ArrayList&lt;&gt;();</span>
<span class="fc" id="L148">        Iterator&lt;Integer&gt; docListIterator = fullDocList.iterator();</span>
<span class="fc" id="L149">        Integer docListId = null;</span>
<span class="fc bfc" id="L150" title="All 2 branches covered.">        while (docListIterator.hasNext()) {</span>
<span class="fc" id="L151">          docListId = docListIterator.next();</span>
<span class="fc bfc" id="L152" title="All 2 branches covered.">          if ((docListId &gt;= lrc.docBase)</span>
<span class="fc bfc" id="L153" title="All 2 branches covered.">              &amp;&amp; (docListId &lt; lrc.docBase + lrc.reader().maxDoc())) {</span>
<span class="fc" id="L154">            docList.add(docListId);</span>
          }
        }
<span class="fc" id="L157">        Collections.sort(docList);</span>
      }

<span class="fc" id="L160">      Terms t = rawReader.leaves().get(lrc.ord).reader().terms(field);</span>
<span class="pc bpc" id="L161" title="1 of 2 branches missed.">      CodecInfo mtasCodecInfo = t == null ? null</span>
<span class="fc" id="L162">          : CodecInfo.getCodecInfoFromTerms(t);</span>

<span class="fc" id="L164">      collectSpansPositionsAndTokens(spansQueryWeight, searcher, mtasCodecInfo,</span>
          r, lrc, field, t, docSet, docList, fieldInfo,
<span class="fc" id="L166">          rawReader.leaves().get(lrc.ord).reader().getFieldInfos());</span>
<span class="fc" id="L167">      collectPrefixes(rawReader.leaves().get(lrc.ord).reader().getFieldInfos(),</span>
          field, fieldInfo);
<span class="fc" id="L169">    }</span>

    // check termvectors
<span class="fc bfc" id="L172" title="All 2 branches covered.">    if (!fieldInfo.termVectorList.isEmpty()</span>
<span class="fc bfc" id="L173" title="All 2 branches covered.">        &amp;&amp; needSecondRoundTermvector(fieldInfo.termVectorList)) {</span>
      // check positions
<span class="fc" id="L175">      boolean needPositions = false;</span>
<span class="pc bpc" id="L176" title="1 of 2 branches missed.">      if (!fieldInfo.termVectorList.isEmpty()) {</span>
<span class="fc bfc" id="L177" title="All 2 branches covered.">        for (ComponentTermVector ctv : fieldInfo.termVectorList) {</span>
<span class="pc bpc" id="L178" title="1 of 2 branches missed.">          if (!needPositions) {</span>
<span class="pc bpc" id="L179" title="1 of 2 branches missed.">            needPositions = ctv.functions != null ? ctv.functionNeedPositions()</span>
                : needPositions;
          }
<span class="fc" id="L182">        }</span>
      }
<span class="fc" id="L184">      Map&lt;Integer, Integer&gt; positionsData = null;</span>

      // loop
<span class="fc" id="L187">      iterator = reader.leaves().listIterator();</span>
<span class="fc bfc" id="L188" title="All 2 branches covered.">      while (iterator.hasNext()) {</span>
<span class="fc" id="L189">        LeafReaderContext lrc = iterator.next();</span>
<span class="fc" id="L190">        LeafReader r = lrc.reader();</span>
<span class="fc" id="L191">        List&lt;Integer&gt; docSet = docSets.get(lrc.ord);</span>
<span class="fc" id="L192">        Terms t = rawReader.leaves().get(lrc.ord).reader().terms(field);</span>
<span class="pc bpc" id="L193" title="1 of 2 branches missed.">        if (needPositions) {</span>
<span class="nc bnc" id="L194" title="All 2 branches missed.">          CodecInfo mtasCodecInfo = t == null ? null</span>
<span class="nc" id="L195">              : CodecInfo.getCodecInfoFromTerms(t);</span>
<span class="nc" id="L196">          positionsData = computePositions(mtasCodecInfo, r, lrc, field,</span>
              docSet);
        }
<span class="fc" id="L199">        createTermvectorSecondRound(fieldInfo.termVectorList, positionsData,</span>
<span class="fc" id="L200">            docSets.get(lrc.ord), t, r, lrc);</span>
<span class="fc" id="L201">      }</span>
    }
<span class="fc" id="L203">  }</span>

  /**
   * Collect collection.
   *
   * @param reader the reader
   * @param docSet the doc set
   * @param collectionInfo the collection info
   * @throws IOException Signals that an I/O exception has occurred.
   */
  public static void collectCollection(IndexReader reader, List&lt;Integer&gt; docSet,
      ComponentCollection collectionInfo) throws IOException {
<span class="fc bfc" id="L215" title="All 2 branches covered.">    if (collectionInfo.action().equals(ComponentCollection.ACTION_CHECK)) {</span>
      // can't do anything in lucene for check
<span class="fc" id="L217">    } else if (collectionInfo.action()</span>
<span class="fc bfc" id="L218" title="All 2 branches covered.">        .equals(ComponentCollection.ACTION_LIST)) {</span>
      // can't do anything in lucene for list
<span class="fc" id="L220">    } else if (collectionInfo.action()</span>
<span class="fc bfc" id="L221" title="All 2 branches covered.">        .equals(ComponentCollection.ACTION_CREATE)) {</span>
<span class="fc" id="L222">      BytesRef term = null;</span>
<span class="fc" id="L223">      PostingsEnum postingsEnum = null;</span>
      Integer docId;
<span class="fc" id="L225">      Integer termDocId = -1;</span>
      Terms terms;
      LeafReaderContext lrc;
      LeafReader r;
<span class="fc" id="L229">      ListIterator&lt;LeafReaderContext&gt; iterator = reader.leaves().listIterator();</span>
<span class="fc bfc" id="L230" title="All 2 branches covered.">      while (iterator.hasNext()) {</span>
<span class="fc" id="L231">        lrc = iterator.next();</span>
<span class="fc" id="L232">        r = lrc.reader();</span>
<span class="fc bfc" id="L233" title="All 2 branches covered.">        for (String field : collectionInfo.fields()) {</span>
<span class="pc bpc" id="L234" title="1 of 2 branches missed.">          if ((terms = r.fields().terms(field)) != null) {</span>
<span class="fc" id="L235">            TermsEnum termsEnum = terms.iterator();</span>
<span class="fc bfc" id="L236" title="All 2 branches covered.">            while ((term = termsEnum.next()) != null) {</span>
<span class="fc" id="L237">              Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="fc" id="L238">              postingsEnum = termsEnum.postings(postingsEnum,</span>
                  PostingsEnum.NONE);
<span class="fc" id="L240">              termDocId = -1;</span>
<span class="pc bpc" id="L241" title="1 of 2 branches missed.">              while (docIterator.hasNext()) {</span>
<span class="fc" id="L242">                docId = docIterator.next() - lrc.docBase;</span>
<span class="fc bfc" id="L243" title="All 4 branches covered.">                if ((docId &gt;= termDocId) &amp;&amp; ((docId.equals(termDocId))</span>
<span class="fc" id="L244">                    || ((termDocId = postingsEnum.advance(docId))</span>
<span class="fc bfc" id="L245" title="All 2 branches covered.">                        .equals(docId)))) {</span>
<span class="fc" id="L246">                  collectionInfo.addValue(term.utf8ToString());</span>
<span class="fc" id="L247">                  break;</span>
                }
<span class="pc bpc" id="L249" title="1 of 2 branches missed.">                if (termDocId.equals(PostingsEnum.NO_MORE_DOCS)) {</span>
<span class="nc" id="L250">                  break;</span>
                }
              }
<span class="fc" id="L253">            }</span>
          }
<span class="fc" id="L255">        }</span>
      }
    }
<span class="fc" id="L258">  }</span>

  /**
   * Collect spans positions and tokens.
   *
   * @param spansQueryWeight the spans query weight
   * @param searcher the searcher
   * @param mtasCodecInfo the mtas codec info
   * @param r the r
   * @param lrc the lrc
   * @param field the field
   * @param t the t
   * @param docSet the doc set
   * @param docList the doc list
   * @param fieldInfo the field info
   * @param fieldInfos the field infos
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void collectSpansPositionsAndTokens(
      Map&lt;MtasSpanQuery, SpanWeight&gt; spansQueryWeight, IndexSearcher searcher,
      CodecInfo mtasCodecInfo, LeafReader r, LeafReaderContext lrc,
      String field, Terms t, List&lt;Integer&gt; docSet, List&lt;Integer&gt; docList,
      ComponentField fieldInfo, FieldInfos fieldInfos) throws IOException {

<span class="fc" id="L282">    boolean needSpans = false;</span>
<span class="fc" id="L283">    boolean needPositions = false;</span>
<span class="fc" id="L284">    boolean needTokens = false;</span>

    // results
<span class="fc" id="L287">    Map&lt;Integer, Integer&gt; positionsData = null;</span>
<span class="fc" id="L288">    Map&lt;Integer, Integer&gt; tokensData = null;</span>
<span class="fc" id="L289">    Map&lt;MtasSpanQuery, Map&lt;Integer, Integer&gt;&gt; spansNumberData = null;</span>
<span class="fc" id="L290">    Map&lt;MtasSpanQuery, Map&lt;Integer, List&lt;Match&gt;&gt;&gt; spansMatchData = null;</span>
<span class="fc" id="L291">    Map&lt;String, SortedMap&lt;String, int[]&gt;&gt; facetData = null;</span>
<span class="fc" id="L292">    Map&lt;String, String&gt; facetDataType = null;</span>

    // collect position stats
<span class="fc bfc" id="L295" title="All 2 branches covered.">    if (!fieldInfo.statsPositionList.isEmpty()) {</span>
<span class="fc" id="L296">      needPositions = true;</span>
    }
    // collect token stats
<span class="fc bfc" id="L299" title="All 2 branches covered.">    if (!fieldInfo.statsTokenList.isEmpty()) {</span>
<span class="fc" id="L300">      needTokens = true;</span>
    }
<span class="fc bfc" id="L302" title="All 2 branches covered.">    if (!fieldInfo.termVectorList.isEmpty()) {</span>
<span class="fc bfc" id="L303" title="All 2 branches covered.">      for (ComponentTermVector ctv : fieldInfo.termVectorList) {</span>
<span class="fc bfc" id="L304" title="All 2 branches covered.">        if (!needPositions) {</span>
<span class="pc bpc" id="L305" title="1 of 2 branches missed.">          needPositions = (ctv.functions == null</span>
<span class="pc" id="L306">              ? ctv.subComponentFunction.parserFunction.needPositions()</span>
<span class="fc" id="L307">              : ctv.functionNeedPositions());</span>
        }
<span class="fc" id="L309">      }</span>
    }

    // compute from spans for selected docs
<span class="fc bfc" id="L313" title="All 2 branches covered.">    if (!fieldInfo.spanQueryList.isEmpty()) {</span>
      // check for statsSpans
<span class="fc" id="L315">      spansNumberData = new HashMap&lt;&gt;();</span>
<span class="fc" id="L316">      spansMatchData = new HashMap&lt;&gt;();</span>
<span class="fc" id="L317">      facetData = new HashMap&lt;&gt;();</span>
<span class="fc" id="L318">      facetDataType = new HashMap&lt;&gt;();</span>
      // spans
<span class="pc bpc" id="L320" title="1 of 2 branches missed.">      if (!fieldInfo.statsSpanList.isEmpty()) {</span>
<span class="fc bfc" id="L321" title="All 2 branches covered.">        for (ComponentSpan cs : fieldInfo.statsSpanList) {</span>
<span class="fc bfc" id="L322" title="All 2 branches covered.">          needPositions = (!needPositions) ? cs.parser.needPositions()</span>
              : needPositions;
<span class="fc bfc" id="L324" title="All 2 branches covered.">          needPositions = (!needPositions) ? cs.functionNeedPositions()</span>
              : needPositions;
<span class="pc bpc" id="L326" title="1 of 4 branches missed.">          needSpans = (!needSpans) ? cs.parser.needArgumentsNumber() &gt; 0</span>
              : needSpans;
<span class="fc" id="L328">          HashSet&lt;Integer&gt; arguments = cs.parser.needArgument();</span>
<span class="fc" id="L329">          arguments.addAll(cs.functionNeedArguments());</span>
<span class="fc bfc" id="L330" title="All 2 branches covered.">          for (int a : arguments) {</span>
<span class="pc bpc" id="L331" title="1 of 2 branches missed.">            if (cs.queries.length &gt; a) {</span>
<span class="fc" id="L332">              MtasSpanQuery q = cs.queries[a];</span>
<span class="fc bfc" id="L333" title="All 2 branches covered.">              if (!spansNumberData.containsKey(q)) {</span>
<span class="fc" id="L334">                spansNumberData.put(q, new HashMap&lt;Integer, Integer&gt;());</span>
              }
            }
<span class="fc" id="L337">          }</span>
<span class="fc" id="L338">        }</span>
      }
      // kwic
<span class="pc bpc" id="L341" title="1 of 2 branches missed.">      if (!fieldInfo.kwicList.isEmpty()) {</span>
<span class="nc" id="L342">        needSpans = true;</span>
<span class="nc bnc" id="L343" title="All 2 branches missed.">        for (ComponentKwic ck : fieldInfo.kwicList) {</span>
<span class="nc bnc" id="L344" title="All 2 branches missed.">          if (!spansMatchData.containsKey(ck.query)) {</span>
<span class="nc" id="L345">            spansMatchData.put(ck.query, new HashMap&lt;Integer, List&lt;Match&gt;&gt;());</span>
          }
<span class="nc" id="L347">        }</span>
      }
      // list
<span class="pc bpc" id="L350" title="1 of 2 branches missed.">      if (!fieldInfo.listList.isEmpty()) {</span>
<span class="nc" id="L351">        needSpans = true;</span>
<span class="nc bnc" id="L352" title="All 2 branches missed.">        for (ComponentList cl : fieldInfo.listList) {</span>
<span class="nc bnc" id="L353" title="All 2 branches missed.">          if (!spansMatchData.containsKey(cl.spanQuery)) {</span>
<span class="nc bnc" id="L354" title="All 2 branches missed.">            if (cl.number &gt; 0) {</span>
              // only if needed
<span class="nc bnc" id="L356" title="All 2 branches missed.">              if (cl.position &lt; (cl.start + cl.number)) {</span>
<span class="nc" id="L357">                spansMatchData.put(cl.spanQuery,</span>
                    new HashMap&lt;Integer, List&lt;Match&gt;&gt;());
              } else {
<span class="nc" id="L360">                spansNumberData.put(cl.spanQuery,</span>
                    new HashMap&lt;Integer, Integer&gt;());
              }
<span class="nc bnc" id="L363" title="All 2 branches missed.">            } else if (!spansNumberData.containsKey(cl.spanQuery)) {</span>
<span class="nc" id="L364">              spansNumberData.put(cl.spanQuery,</span>
                  new HashMap&lt;Integer, Integer&gt;());
            }
          }
<span class="nc" id="L368">        }</span>
      }
      // group
<span class="fc bfc" id="L371" title="All 2 branches covered.">      if (!fieldInfo.groupList.isEmpty()) {</span>
<span class="fc" id="L372">        needSpans = true;</span>
<span class="fc bfc" id="L373" title="All 2 branches covered.">        for (ComponentGroup cg : fieldInfo.groupList) {</span>
<span class="pc bpc" id="L374" title="1 of 2 branches missed.">          if (!spansMatchData.containsKey(cg.spanQuery)) {</span>
<span class="fc" id="L375">            spansMatchData.put(cg.spanQuery,</span>
                new HashMap&lt;Integer, List&lt;Match&gt;&gt;());
          }
<span class="fc" id="L378">        }</span>
      }
      // facet
<span class="pc bpc" id="L381" title="1 of 2 branches missed.">      if (!fieldInfo.facetList.isEmpty()) {</span>
<span class="nc bnc" id="L382" title="All 2 branches missed.">        for (ComponentFacet cf : fieldInfo.facetList) {</span>
<span class="nc bnc" id="L383" title="All 2 branches missed.">          needPositions = !needPositions ? cf.baseParserNeedPositions()</span>
              : needPositions;
<span class="nc bnc" id="L385" title="All 2 branches missed.">          needPositions = !needPositions ? cf.functionNeedPositions()</span>
              : needPositions;
<span class="nc bnc" id="L387" title="All 2 branches missed.">          for (int i = 0; i &lt; cf.baseFields.length; i++) {</span>
<span class="nc bnc" id="L388" title="All 4 branches missed.">            needSpans = !needSpans ? cf.baseParsers[i].needArgumentsNumber() &gt; 0</span>
                : needSpans;
<span class="nc" id="L390">            HashSet&lt;Integer&gt; arguments = cf.baseParsers[i].needArgument();</span>
<span class="nc bnc" id="L391" title="All 2 branches missed.">            for (int a : arguments) {</span>
<span class="nc bnc" id="L392" title="All 2 branches missed.">              if (cf.spanQueries.length &gt; a) {</span>
<span class="nc" id="L393">                MtasSpanQuery q = cf.spanQueries[a];</span>
<span class="nc bnc" id="L394" title="All 2 branches missed.">                if (!spansNumberData.containsKey(q)) {</span>
<span class="nc" id="L395">                  spansNumberData.put(q, new HashMap&lt;Integer, Integer&gt;());</span>
                }
              }
<span class="nc" id="L398">            }</span>
<span class="nc bnc" id="L399" title="All 2 branches missed.">            for (MtasFunctionParserFunction function : cf.baseFunctionParserFunctions[i]) {</span>
<span class="nc bnc" id="L400" title="All 4 branches missed.">              needSpans = !needSpans ? function.needArgumentsNumber() &gt; 0</span>
                  : needSpans;
<span class="nc" id="L402">              arguments = function.needArgument();</span>
<span class="nc bnc" id="L403" title="All 2 branches missed.">              for (int a : arguments) {</span>
<span class="nc bnc" id="L404" title="All 2 branches missed.">                if (cf.spanQueries.length &gt; a) {</span>
<span class="nc" id="L405">                  MtasSpanQuery q = cf.spanQueries[a];</span>
<span class="nc bnc" id="L406" title="All 2 branches missed.">                  if (!spansNumberData.containsKey(q)) {</span>
<span class="nc" id="L407">                    spansNumberData.put(q, new HashMap&lt;Integer, Integer&gt;());</span>
                  }
                }
<span class="nc" id="L410">              }</span>
            }
<span class="nc bnc" id="L412" title="All 2 branches missed.">            if (!facetData.containsKey(cf.baseFields[i])) {</span>
<span class="nc" id="L413">              facetData.put(cf.baseFields[i], new TreeMap&lt;String, int[]&gt;());</span>
<span class="nc" id="L414">              facetDataType.put(cf.baseFields[i], cf.baseFieldTypes[i]);</span>
            }
          }
<span class="nc" id="L417">        }</span>
      }
      // termvector
<span class="pc bpc" id="L420" title="1 of 2 branches missed.">      if (!fieldInfo.termVectorList.isEmpty()) {</span>
<span class="nc bnc" id="L421" title="All 2 branches missed.">        for (ComponentTermVector ctv : fieldInfo.termVectorList) {</span>
<span class="nc bnc" id="L422" title="All 2 branches missed.">          if ((ctv.subComponentFunction.parserFunction != null</span>
<span class="nc bnc" id="L423" title="All 4 branches missed.">              &amp;&amp; ctv.subComponentFunction.parserFunction.needPositions())</span>
<span class="nc bnc" id="L424" title="All 2 branches missed.">              || (ctv.functions != null &amp;&amp; ctv.functionNeedPositions())) {</span>
<span class="nc" id="L425">            needPositions = true;</span>
          }
<span class="nc" id="L427">        }</span>
      }
    }

<span class="fc bfc" id="L431" title="All 2 branches covered.">    if (needSpans) {</span>
      Map&lt;Integer, Integer&gt; numberData;
      Map&lt;Integer, List&lt;Match&gt;&gt; matchData;

      // collect values for facetFields
<span class="pc bpc" id="L436" title="1 of 2 branches missed.">      for (Entry&lt;String, SortedMap&lt;String, int[]&gt;&gt; entry : facetData</span>
<span class="fc" id="L437">          .entrySet()) {</span>
<span class="nc" id="L438">        Terms fft = r.terms(entry.getKey());</span>
<span class="nc bnc" id="L439" title="All 2 branches missed.">        if (fft != null) {</span>
<span class="nc" id="L440">          TermsEnum termsEnum = fft.iterator();</span>
<span class="nc" id="L441">          BytesRef term = null;</span>
<span class="nc" id="L442">          PostingsEnum postingsEnum = null;</span>
<span class="nc" id="L443">          SortedMap&lt;String, int[]&gt; facetDataList = entry.getValue();</span>
<span class="nc bnc" id="L444" title="All 2 branches missed.">          while ((term = termsEnum.next()) != null) {</span>
            int docId;
<span class="nc" id="L446">            int termDocId = -1;</span>
<span class="nc" id="L447">            int[] facetDataSublist = new int[docSet.size()];</span>
<span class="nc" id="L448">            int facetDataSublistCounter = 0;</span>
<span class="nc" id="L449">            Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="nc" id="L450">            postingsEnum = termsEnum.postings(postingsEnum);</span>
<span class="nc bnc" id="L451" title="All 2 branches missed.">            while (docIterator.hasNext()) {</span>
<span class="nc" id="L452">              docId = docIterator.next() - lrc.docBase;</span>
<span class="nc bnc" id="L453" title="All 4 branches missed.">              if (docId &gt;= termDocId &amp;&amp; ((docId == termDocId)</span>
<span class="nc bnc" id="L454" title="All 2 branches missed.">                  || ((termDocId = postingsEnum.advance(docId)) == docId))) {</span>
<span class="nc" id="L455">                facetDataSublist[facetDataSublistCounter] = docId + lrc.docBase;</span>
<span class="nc" id="L456">                facetDataSublistCounter++;</span>
              }
            }
<span class="nc bnc" id="L459" title="All 2 branches missed.">            if (facetDataSublistCounter &gt; 0) {</span>
<span class="nc" id="L460">              String termValue = null;</span>
<span class="nc" id="L461">              if (facetDataType.get(entry.getKey())</span>
<span class="nc bnc" id="L462" title="All 2 branches missed.">                  .equals(ComponentFacet.TYPE_INTEGER)) {</span>
                // only values without shifting bits
<span class="nc bnc" id="L464" title="All 2 branches missed.">                if (term.bytes[term.offset] == LegacyNumericUtils.SHIFT_START_INT) {</span>
<span class="nc" id="L465">                  termValue = Integer</span>
<span class="nc" id="L466">                      .toString(LegacyNumericUtils.prefixCodedToInt(term));</span>
                } else {
                  continue;
                }
<span class="nc" id="L470">              } else if (facetDataType.get(entry.getKey())</span>
<span class="nc bnc" id="L471" title="All 2 branches missed.">                  .equals(ComponentFacet.TYPE_LONG)) {</span>
<span class="nc bnc" id="L472" title="All 2 branches missed.">                if (term.bytes[term.offset] == LegacyNumericUtils.SHIFT_START_LONG) {</span>
<span class="nc" id="L473">                  termValue = Long</span>
<span class="nc" id="L474">                      .toString(LegacyNumericUtils.prefixCodedToLong(term));</span>
                } else {
                  continue;
                }
              } else {
<span class="nc" id="L479">                termValue = term.utf8ToString();</span>
              }
<span class="nc bnc" id="L481" title="All 2 branches missed.">              if (!facetDataList.containsKey(termValue)) {</span>
<span class="nc" id="L482">                facetDataList.put(termValue,</span>
<span class="nc" id="L483">                    Arrays.copyOf(facetDataSublist, facetDataSublistCounter));</span>
              } else {
<span class="nc" id="L485">                int[] oldList = facetDataList.get(termValue);</span>
<span class="nc" id="L486">                int[] newList = new int[oldList.length</span>
                    + facetDataSublistCounter];
<span class="nc" id="L488">                System.arraycopy(oldList, 0, newList, 0, oldList.length);</span>
<span class="nc" id="L489">                System.arraycopy(facetDataSublist, 0, newList, oldList.length,</span>
                    facetDataSublistCounter);
<span class="nc" id="L491">                facetDataList.put(termValue, newList);</span>
              }
            }
<span class="nc" id="L494">          }</span>
        }
<span class="nc" id="L496">      }</span>

<span class="fc bfc" id="L498" title="All 2 branches covered.">      for (MtasSpanQuery sq : fieldInfo.spanQueryList) {</span>
        // what to collect
<span class="pc bpc" id="L500" title="1 of 2 branches missed.">        if (spansNumberData.containsKey(sq)) {</span>
<span class="fc" id="L501">          numberData = spansNumberData.get(sq);</span>
        } else {
<span class="nc" id="L503">          numberData = null;</span>
        }
<span class="fc bfc" id="L505" title="All 2 branches covered.">        if (spansMatchData.containsKey(sq)) {</span>
<span class="fc" id="L506">          matchData = spansMatchData.get(sq);</span>
        } else {
<span class="fc" id="L508">          matchData = null;</span>
        }
<span class="pc bpc" id="L510" title="3 of 4 branches missed.">        if ((numberData != null) || (matchData != null)) {</span>
<span class="fc" id="L511">          Spans spans = spansQueryWeight.get(sq).getSpans(lrc,</span>
              SpanWeight.Postings.POSITIONS);
<span class="fc bfc" id="L513" title="All 2 branches covered.">          if (spans != null) {</span>
            Iterator&lt;Integer&gt; it;
<span class="pc bpc" id="L515" title="1 of 2 branches missed.">            if (docSet != null) {</span>
<span class="fc" id="L516">              it = docSet.iterator();</span>
            } else {
<span class="nc" id="L518">              it = docList.iterator();</span>
            }
<span class="pc bpc" id="L520" title="1 of 2 branches missed.">            if (it.hasNext()) {</span>
<span class="fc" id="L521">              int docId = it.next();</span>
              int number;
              ArrayList&lt;Match&gt; matchDataList;
<span class="fc" id="L524">              Integer spansDocId = null;</span>
<span class="pc bpc" id="L525" title="1 of 2 branches missed.">              while (docId != DocIdSetIterator.NO_MORE_DOCS) {</span>
<span class="fc bfc" id="L526" title="All 2 branches covered.">                if (spans.advance(</span>
                    (docId - lrc.docBase)) == DocIdSetIterator.NO_MORE_DOCS) {
<span class="fc" id="L528">                  break;</span>
                }
<span class="fc" id="L530">                spansDocId = spans.docID() + lrc.docBase;</span>
<span class="pc bpc" id="L531" title="1 of 4 branches missed.">                while ((docId &lt; spansDocId) &amp;&amp; it.hasNext()) {</span>
<span class="fc" id="L532">                  docId = it.next();</span>
                }
<span class="pc bpc" id="L534" title="1 of 2 branches missed.">                if (docId &lt; spansDocId) {</span>
<span class="nc" id="L535">                  break;</span>
                }
<span class="pc bpc" id="L537" title="1 of 2 branches missed.">                if (spansDocId.equals(docId)) {</span>
<span class="fc" id="L538">                  number = 0;</span>
<span class="fc" id="L539">                  matchDataList = new ArrayList&lt;&gt;();</span>
                  int tmpStartPosition;
<span class="fc" id="L541">                  while ((tmpStartPosition = spans</span>
<span class="fc bfc" id="L542" title="All 2 branches covered.">                      .nextStartPosition()) != Spans.NO_MORE_POSITIONS) {</span>
<span class="fc" id="L543">                    number++;</span>
<span class="fc bfc" id="L544" title="All 2 branches covered.">                    if (matchData != null) {</span>
<span class="fc" id="L545">                      Match m = new Match(tmpStartPosition,</span>
<span class="fc" id="L546">                          spans.endPosition());</span>
<span class="fc" id="L547">                      matchDataList.add(m);</span>
<span class="fc" id="L548">                    }</span>
                  }
<span class="pc bpc" id="L550" title="1 of 2 branches missed.">                  if ((numberData != null)) {</span>
<span class="fc" id="L551">                    numberData.put(spansDocId, number);</span>
                  }
<span class="fc bfc" id="L553" title="All 2 branches covered.">                  if ((matchData != null)) {</span>
<span class="fc" id="L554">                    matchData.put(spansDocId, matchDataList);</span>
                  }
<span class="fc bfc" id="L556" title="All 2 branches covered.">                  if (it.hasNext()) {</span>
<span class="fc" id="L557">                    docId = it.next();</span>
                  } else {
                    break;
                  }
<span class="fc" id="L561">                }</span>
              }
            }
          }
        }
<span class="fc" id="L566">      }</span>
    }

    // collect position stats
<span class="fc bfc" id="L570" title="All 2 branches covered.">    if (needPositions) {</span>
<span class="pc bpc" id="L571" title="1 of 2 branches missed.">      if (mtasCodecInfo != null) {</span>
        // for relatively small numbers, compute only what is needed
<span class="fc bfc" id="L573" title="All 2 branches covered.">        if (docSet.size() &lt; Math.log(r.maxDoc())) {</span>
<span class="fc" id="L574">          positionsData = new HashMap&lt;&gt;();</span>
<span class="fc bfc" id="L575" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="fc" id="L576">            positionsData.put(docId, mtasCodecInfo.getNumberOfPositions(field,</span>
                (docId - lrc.docBase)));
<span class="fc" id="L578">          }</span>
          // compute everything, only use what is needed
        } else {
<span class="fc" id="L581">          positionsData = mtasCodecInfo.getAllNumberOfPositions(field,</span>
              lrc.docBase);
<span class="fc bfc" id="L583" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="pc bpc" id="L584" title="1 of 2 branches missed.">            if (!positionsData.containsKey(docId)) {</span>
<span class="nc" id="L585">              positionsData.put(docId, 0);</span>
            }
<span class="fc" id="L587">          }</span>
        }
      } else {
<span class="nc" id="L590">        positionsData = new HashMap&lt;&gt;();</span>
<span class="nc bnc" id="L591" title="All 2 branches missed.">        for (int docId : docSet) {</span>
<span class="nc" id="L592">          positionsData.put(docId, 0);</span>
<span class="nc" id="L593">        }</span>
      }
    }

    // collect token stats
<span class="fc bfc" id="L598" title="All 2 branches covered.">    if (needTokens) {</span>
<span class="pc bpc" id="L599" title="1 of 2 branches missed.">      if (mtasCodecInfo != null) {</span>
        // for relatively small numbers, compute only what is needed
<span class="fc bfc" id="L601" title="All 2 branches covered.">        if (docSet.size() &lt; Math.log(r.maxDoc())) {</span>
<span class="fc" id="L602">          tokensData = new HashMap&lt;&gt;();</span>
<span class="fc bfc" id="L603" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="fc" id="L604">            tokensData.put(docId,</span>
<span class="fc" id="L605">                mtasCodecInfo.getNumberOfTokens(field, (docId - lrc.docBase)));</span>
<span class="fc" id="L606">          }</span>
          // compute everything, only use what is needed
        } else {
<span class="fc" id="L609">          tokensData = mtasCodecInfo.getAllNumberOfTokens(field, lrc.docBase);</span>
<span class="fc bfc" id="L610" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="pc bpc" id="L611" title="1 of 2 branches missed.">            if (!tokensData.containsKey(docId)) {</span>
<span class="nc" id="L612">              tokensData.put(docId, 0);</span>
            }
<span class="fc" id="L614">          }</span>
        }
      } else {
<span class="nc" id="L617">        tokensData = new HashMap&lt;&gt;();</span>
<span class="nc bnc" id="L618" title="All 2 branches missed.">        for (int docId : docSet) {</span>
<span class="nc" id="L619">          tokensData.put(docId, 0);</span>
<span class="nc" id="L620">        }</span>
      }
    }

<span class="fc bfc" id="L624" title="All 2 branches covered.">    if (!fieldInfo.statsPositionList.isEmpty()) {</span>
      // create positions
<span class="fc" id="L626">      createPositions(fieldInfo.statsPositionList, positionsData, docSet);</span>
    }

<span class="fc bfc" id="L629" title="All 2 branches covered.">    if (!fieldInfo.statsTokenList.isEmpty()) {</span>
      // create positions
<span class="fc" id="L631">      createTokens(fieldInfo.statsTokenList, tokensData, docSet);</span>
    }

<span class="pc bpc" id="L634" title="1 of 2 branches missed.">    if (!fieldInfo.documentList.isEmpty()) {</span>
      // create document
<span class="nc" id="L636">      createDocument(fieldInfo.documentList, docList, fieldInfo.uniqueKeyField,</span>
          searcher, t, lrc);
    }
<span class="fc bfc" id="L639" title="All 2 branches covered.">    if (!fieldInfo.spanQueryList.isEmpty()) {</span>
<span class="pc bpc" id="L640" title="1 of 2 branches missed.">      if (!fieldInfo.statsSpanList.isEmpty()) {</span>
        // create stats
<span class="fc" id="L642">        createStats(fieldInfo.statsSpanList, positionsData, spansNumberData,</span>
<span class="fc" id="L643">            docSet.toArray(new Integer[docSet.size()]));</span>
      }
<span class="pc bpc" id="L645" title="1 of 2 branches missed.">      if (!fieldInfo.listList.isEmpty()) {</span>
        // create list
<span class="nc" id="L647">        createList(fieldInfo.listList, spansNumberData, spansMatchData, docSet,</span>
            field, lrc.docBase, fieldInfo.uniqueKeyField, mtasCodecInfo,
            searcher);
      }
<span class="fc bfc" id="L651" title="All 2 branches covered.">      if (!fieldInfo.groupList.isEmpty()) {</span>
        // create group
<span class="fc" id="L653">        createGroup(fieldInfo.groupList, spansMatchData, docSet,</span>
<span class="fc" id="L654">            fieldInfos.fieldInfo(field), field, lrc.docBase, mtasCodecInfo,</span>
            searcher, lrc);
      }
<span class="pc bpc" id="L657" title="1 of 2 branches missed.">      if (!fieldInfo.kwicList.isEmpty()) {</span>
        // create kwic
<span class="nc" id="L659">        createKwic(fieldInfo.kwicList, spansMatchData, docList, field,</span>
            lrc.docBase, fieldInfo.uniqueKeyField, mtasCodecInfo, searcher);
      }
<span class="pc bpc" id="L662" title="1 of 2 branches missed.">      if (!fieldInfo.facetList.isEmpty()) {</span>
        // create facets
<span class="nc" id="L664">        createFacet(fieldInfo.facetList, positionsData, spansNumberData,</span>
            facetData, docSet);
      }
    }
<span class="fc bfc" id="L668" title="All 2 branches covered.">    if (!fieldInfo.termVectorList.isEmpty()) {</span>
<span class="fc" id="L669">      createTermvectorFull(fieldInfo.termVectorList, positionsData, docSet, t,</span>
          r, lrc);
<span class="fc" id="L671">      createTermvectorFirstRound(fieldInfo.termVectorList, positionsData,</span>
          docSet, t, r, lrc);
    }
<span class="fc" id="L674">  }</span>

  /**
   * Collect known prefixes.
   *
   * @param fi the fi
   * @return the sets the
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static Set&lt;String&gt; collectKnownPrefixes(FieldInfo fi)
      throws IOException {
<span class="pc bpc" id="L685" title="1 of 2 branches missed.">    if (fi != null) {</span>
<span class="fc" id="L686">      HashSet&lt;String&gt; result = new HashSet&lt;&gt;();</span>
<span class="fc" id="L687">      String singlePositionPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SINGLE_POSITION);
<span class="fc" id="L689">      String multiplePositionPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_MULTIPLE_POSITION);
<span class="fc" id="L691">      String setPositionPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SET_POSITION);
<span class="pc bpc" id="L693" title="1 of 2 branches missed.">      if (singlePositionPrefixes != null) {</span>
<span class="fc" id="L694">        String[] prefixes = singlePositionPrefixes</span>
<span class="fc" id="L695">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L696" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L697">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L698" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L699">            result.add(item);</span>
          }
        }
      }
<span class="pc bpc" id="L703" title="1 of 2 branches missed.">      if (multiplePositionPrefixes != null) {</span>
<span class="fc" id="L704">        String[] prefixes = multiplePositionPrefixes</span>
<span class="fc" id="L705">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L706" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L707">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L708" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L709">            result.add(item);</span>
          }
        }
      }
<span class="pc bpc" id="L713" title="1 of 2 branches missed.">      if (setPositionPrefixes != null) {</span>
<span class="fc" id="L714">        String[] prefixes = setPositionPrefixes</span>
<span class="fc" id="L715">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L716" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L717">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L718" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L719">            result.add(item);</span>
          }
        }
      }
<span class="fc" id="L723">      return result;</span>
    } else {
<span class="nc" id="L725">      return Collections.emptySet();</span>
    }
  }

  /**
   * Collect intersection prefixes.
   *
   * @param fi the fi
   * @return the sets the
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static Set&lt;String&gt; collectIntersectionPrefixes(FieldInfo fi)
      throws IOException {
<span class="pc bpc" id="L738" title="1 of 2 branches missed.">    if (fi != null) {</span>
<span class="fc" id="L739">      Set&lt;String&gt; result = new HashSet&lt;&gt;();</span>
<span class="fc" id="L740">      String intersectingPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_INTERSECTION);
<span class="pc bpc" id="L742" title="1 of 2 branches missed.">      if (intersectingPrefixes != null) {</span>
<span class="fc" id="L743">        String[] prefixes = intersectingPrefixes</span>
<span class="fc" id="L744">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L745" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L746">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L747" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L748">            result.add(item);</span>
          }
        }
      }
<span class="fc" id="L752">      return result;</span>
    } else {
<span class="nc" id="L754">      return Collections.emptySet();</span>
    }
  }

  /**
   * Collect prefixes.
   *
   * @param fieldInfos the field infos
   * @param field the field
   * @param fieldInfo the field info
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void collectPrefixes(FieldInfos fieldInfos, String field,
      ComponentField fieldInfo) throws IOException {
<span class="fc bfc" id="L768" title="All 2 branches covered.">    if (fieldInfo.prefix != null) {</span>
<span class="fc" id="L769">      FieldInfo fi = fieldInfos.fieldInfo(field);</span>
<span class="pc bpc" id="L770" title="1 of 2 branches missed.">      if (fi != null) {</span>
<span class="fc" id="L771">        String singlePositionPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SINGLE_POSITION);
<span class="fc" id="L773">        String multiplePositionPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_MULTIPLE_POSITION);
<span class="fc" id="L775">        String setPositionPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SET_POSITION);
<span class="fc" id="L777">        String intersectingPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_INTERSECTION);
<span class="pc bpc" id="L779" title="1 of 2 branches missed.">        if (singlePositionPrefixes != null) {</span>
<span class="fc" id="L780">          String[] prefixes = singlePositionPrefixes</span>
<span class="fc" id="L781">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L782" title="All 2 branches covered.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L783">            fieldInfo.prefix.addSinglePosition(prefixes[i]);</span>
          }
        }
<span class="pc bpc" id="L786" title="1 of 2 branches missed.">        if (multiplePositionPrefixes != null) {</span>
<span class="fc" id="L787">          String[] prefixes = multiplePositionPrefixes</span>
<span class="fc" id="L788">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L789" title="All 2 branches covered.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L790">            fieldInfo.prefix.addMultiplePosition(prefixes[i]);</span>
          }
        }
<span class="pc bpc" id="L793" title="1 of 2 branches missed.">        if (setPositionPrefixes != null) {</span>
<span class="fc" id="L794">          String[] prefixes = setPositionPrefixes</span>
<span class="fc" id="L795">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L796" title="All 2 branches covered.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L797">            fieldInfo.prefix.addSetPosition(prefixes[i]);</span>
          }
        }
<span class="pc bpc" id="L800" title="1 of 2 branches missed.">        if (intersectingPrefixes != null) {</span>
<span class="fc" id="L801">          String[] prefixes = intersectingPrefixes</span>
<span class="fc" id="L802">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L803" title="All 2 branches covered.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L804">            fieldInfo.prefix.addIntersecting(prefixes[i]);</span>
          }
        }
      }
    }
<span class="fc" id="L809">  }</span>

  /**
   * Collect spans for occurences.
   *
   * @param occurences the occurences
   * @param prefixes the prefixes
   * @param field the field
   * @param searcher the searcher
   * @param lrc the lrc
   * @return the map
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static Map&lt;GroupHit, Spans&gt; collectSpansForOccurences(
      Set&lt;GroupHit&gt; occurences, Set&lt;String&gt; prefixes, String field,
      IndexSearcher searcher, LeafReaderContext lrc) throws IOException {
<span class="nc" id="L825">    Map&lt;GroupHit, Spans&gt; list = new HashMap&lt;&gt;();</span>
<span class="nc" id="L826">    IndexReader reader = searcher.getIndexReader();</span>
<span class="nc bnc" id="L827" title="All 2 branches missed.">    for (GroupHit hit : occurences) {</span>
<span class="nc" id="L828">      MtasSpanQuery queryHit = createQueryFromGroupHit(prefixes, field, hit);</span>
<span class="nc bnc" id="L829" title="All 2 branches missed.">      if (queryHit != null) {</span>
<span class="nc" id="L830">        MtasSpanQuery queryHitRewritten = queryHit.rewrite(reader);</span>
<span class="nc" id="L831">        SpanWeight weight = queryHitRewritten.createWeight(searcher, false);</span>
<span class="nc" id="L832">        Spans spans = weight.getSpans(lrc, SpanWeight.Postings.POSITIONS);</span>
<span class="nc bnc" id="L833" title="All 2 branches missed.">        if (spans != null) {</span>
<span class="nc" id="L834">          list.put(hit, spans);</span>
        }
      }
<span class="nc" id="L837">    }</span>
<span class="nc" id="L838">    return list;</span>
  }

  /**
   * Creates the query from group hit.
   *
   * @param prefixes the prefixes
   * @param field the field
   * @param hit the hit
   * @return the mtas span query
   */
  private static MtasSpanQuery createQueryFromGroupHit(Set&lt;String&gt; prefixes,
      String field, GroupHit hit) {
    // initial check
<span class="nc bnc" id="L852" title="All 6 branches missed.">    if (prefixes == null || field == null || hit == null) {</span>
<span class="nc" id="L853">      return null;</span>
    } else {
<span class="nc" id="L855">      MtasSpanQuery query = null;</span>
<span class="nc" id="L856">      MtasSpanQuery hitQuery = null;</span>
      // check for missing
<span class="nc bnc" id="L858" title="All 4 branches missed.">      if (hit.missingLeft != null &amp;&amp; hit.missingLeft.length &gt; 0) {</span>
<span class="nc bnc" id="L859" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.missingLeft.length; i++) {</span>
<span class="nc bnc" id="L860" title="All 2 branches missed.">          if (hit.missingLeft[i].size() != hit.unknownLeft[i].size()) {</span>
<span class="nc" id="L861">            return null;</span>
          }
        }
      }
<span class="nc bnc" id="L865" title="All 4 branches missed.">      if (hit.missingHit != null &amp;&amp; hit.missingHit.length &gt; 0) {</span>
<span class="nc bnc" id="L866" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.missingHit.length; i++) {</span>
<span class="nc bnc" id="L867" title="All 2 branches missed.">          if (hit.missingHit[i].size() != hit.unknownHit[i].size()) {</span>
<span class="nc" id="L868">            return null;</span>
          }
        }
      }
<span class="nc bnc" id="L872" title="All 4 branches missed.">      if (hit.missingRight != null &amp;&amp; hit.missingRight.length &gt; 0) {</span>
<span class="nc bnc" id="L873" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.missingRight.length; i++) {</span>
<span class="nc bnc" id="L874" title="All 2 branches missed.">          if (hit.missingRight[i].size() != hit.unknownRight[i].size()) {</span>
<span class="nc" id="L875">            return null;</span>
          }
        }
      }

<span class="nc bnc" id="L880" title="All 4 branches missed.">      if (hit.dataHit != null &amp;&amp; hit.dataHit.length &gt; 0) {</span>
<span class="nc" id="L881">        List&lt;MtasSpanSequenceItem&gt; items = new ArrayList&lt;&gt;();</span>
<span class="nc bnc" id="L882" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.dataHit.length; i++) {</span>
<span class="nc" id="L883">          MtasSpanQuery item = null;</span>
<span class="nc bnc" id="L884" title="All 2 branches missed.">          if (hit.dataHit[i].isEmpty()) {</span>
<span class="nc" id="L885">            item = new MtasSpanMatchAllQuery(field);</span>
<span class="nc bnc" id="L886" title="All 2 branches missed.">          } else if (hit.dataHit[i].size() == 1) {</span>
<span class="nc" id="L887">            Term term = new Term(field, hit.dataHit[i].get(0));</span>
<span class="nc" id="L888">            item = new MtasSpanTermQuery(term);</span>
<span class="nc" id="L889">          } else {</span>
<span class="nc" id="L890">            MtasSpanQuery[] subList = new MtasSpanQuery[hit.dataHit[i].size()];</span>
<span class="nc bnc" id="L891" title="All 2 branches missed.">            for (int j = 0; j &lt; hit.dataHit[i].size(); j++) {</span>
<span class="nc" id="L892">              Term term = new Term(field, hit.dataHit[i].get(j));</span>
<span class="nc" id="L893">              subList[j] = new MtasSpanTermQuery(term);</span>
            }
<span class="nc" id="L895">            item = new MtasSpanAndQuery(subList);</span>
          }
<span class="nc" id="L897">          items.add(new MtasSpanSequenceItem(item, false));</span>
        }
<span class="nc" id="L899">        hitQuery = new MtasSpanSequenceQuery(items, null, null);</span>
      }
<span class="nc bnc" id="L901" title="All 2 branches missed.">      if (hitQuery != null) {</span>
<span class="nc" id="L902">        query = hitQuery;</span>
      }
<span class="nc" id="L904">      return query;</span>
    }
  }

  /**
   * Compute positions.
   *
   * @param mtasCodecInfo the mtas codec info
   * @param r the r
   * @param lrc the lrc
   * @param field the field
   * @param docSet the doc set
   * @return the map
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static Map&lt;Integer, Integer&gt; computePositions(CodecInfo mtasCodecInfo,
      LeafReader r, LeafReaderContext lrc, String field, List&lt;Integer&gt; docSet)
      throws IOException {
    HashMap&lt;Integer, Integer&gt; positionsData;
<span class="nc bnc" id="L923" title="All 2 branches missed.">    if (mtasCodecInfo != null) {</span>
      // for relatively small numbers, compute only what is needed
<span class="nc bnc" id="L925" title="All 2 branches missed.">      if (docSet.size() &lt; Math.log(r.maxDoc())) {</span>
<span class="nc" id="L926">        positionsData = new HashMap&lt;&gt;();</span>
<span class="nc bnc" id="L927" title="All 2 branches missed.">        for (int docId : docSet) {</span>
<span class="nc" id="L928">          positionsData.put(docId,</span>
<span class="nc" id="L929">              mtasCodecInfo.getNumberOfPositions(field, (docId - lrc.docBase)));</span>
<span class="nc" id="L930">        }</span>
        // compute everything, only use what is needed
      } else {
<span class="nc" id="L933">        positionsData = mtasCodecInfo.getAllNumberOfPositions(field,</span>
            lrc.docBase);
<span class="nc bnc" id="L935" title="All 2 branches missed.">        for (int docId : docSet) {</span>
<span class="nc bnc" id="L936" title="All 2 branches missed.">          if (!positionsData.containsKey(docId)) {</span>
<span class="nc" id="L937">            positionsData.put(docId, 0);</span>
          }
<span class="nc" id="L939">        }</span>
      }
    } else {
<span class="nc" id="L942">      positionsData = new HashMap&lt;&gt;();</span>
<span class="nc bnc" id="L943" title="All 2 branches missed.">      for (int docId : docSet) {</span>
<span class="nc" id="L944">        positionsData.put(docId, 0);</span>
<span class="nc" id="L945">      }</span>
    }
<span class="nc" id="L947">    return positionsData;</span>
  }

  /**
   * Compute arguments.
   *
   * @param spansNumberData the spans number data
   * @param queries the queries
   * @param docSet the doc set
   * @return the map
   */
  private static Map&lt;Integer, long[]&gt; computeArguments(
      Map&lt;MtasSpanQuery, Map&lt;Integer, Integer&gt;&gt; spansNumberData,
      MtasSpanQuery[] queries, Integer[] docSet) {
<span class="fc" id="L961">    Map&lt;Integer, long[]&gt; args = new HashMap&lt;&gt;();</span>
<span class="fc bfc" id="L962" title="All 2 branches covered.">    for (int q = 0; q &lt; queries.length; q++) {</span>
<span class="fc" id="L963">      Map&lt;Integer, Integer&gt; tmpData = spansNumberData.get(queries[q]);</span>
<span class="fc" id="L964">      long[] tmpList = null;</span>
<span class="fc bfc" id="L965" title="All 2 branches covered.">      for (int docId : docSet) {</span>
<span class="pc bpc" id="L966" title="1 of 4 branches missed.">        if (tmpData != null &amp;&amp; tmpData.containsKey(docId)) {</span>
<span class="fc bfc" id="L967" title="All 2 branches covered.">          if (!args.containsKey(docId)) {</span>
<span class="fc" id="L968">            tmpList = new long[queries.length];</span>
          } else {
<span class="fc" id="L970">            tmpList = args.get(docId);</span>
          }
<span class="fc" id="L972">          tmpList[q] = tmpData.get(docId);</span>
<span class="fc" id="L973">          args.put(docId, tmpList);</span>
<span class="pc bpc" id="L974" title="1 of 2 branches missed.">        } else if (!args.containsKey(docId)) {</span>
<span class="fc" id="L975">          tmpList = new long[queries.length];</span>
<span class="fc" id="L976">          args.put(docId, tmpList);</span>
        }
      }
    }
<span class="fc" id="L980">    return args;</span>
  }

  /**
   * Intersected doc list.
   *
   * @param facetDocList the facet doc list
   * @param docSet the doc set
   * @return the integer[]
   */
  private static Integer[] intersectedDocList(int[] facetDocList,
      Integer[] docSet) {
<span class="nc bnc" id="L992" title="All 4 branches missed.">    if (facetDocList != null &amp;&amp; docSet != null) {</span>
<span class="nc" id="L993">      Integer[] c = new Integer[Math.min(facetDocList.length, docSet.length)];</span>
<span class="nc" id="L994">      int ai = 0;</span>
<span class="nc" id="L995">      int bi = 0;</span>
<span class="nc" id="L996">      int ci = 0;</span>
<span class="nc bnc" id="L997" title="All 4 branches missed.">      while (ai &lt; facetDocList.length &amp;&amp; bi &lt; docSet.length) {</span>
<span class="nc bnc" id="L998" title="All 2 branches missed.">        if (facetDocList[ai] &lt; docSet[bi]) {</span>
<span class="nc" id="L999">          ai++;</span>
<span class="nc bnc" id="L1000" title="All 2 branches missed.">        } else if (facetDocList[ai] &gt; docSet[bi]) {</span>
<span class="nc" id="L1001">          bi++;</span>
        } else {
<span class="nc bnc" id="L1003" title="All 4 branches missed.">          if (ci == 0 || facetDocList[ai] != c[ci - 1]) {</span>
<span class="nc" id="L1004">            c[ci++] = facetDocList[ai];</span>
          }
<span class="nc" id="L1006">          ai++;</span>
<span class="nc" id="L1007">          bi++;</span>
        }
      }
<span class="nc" id="L1010">      return Arrays.copyOfRange(c, 0, ci);</span>
    }
<span class="nc" id="L1012">    return new Integer[] {};</span>
  }

  /**
   * Creates the positions.
   *
   * @param statsPositionList the stats position list
   * @param positionsData the positions data
   * @param docSet the doc set
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createPositions(List&lt;ComponentPosition&gt; statsPositionList,
      Map&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet)
      throws IOException {
<span class="pc bpc" id="L1026" title="1 of 2 branches missed.">    if (statsPositionList != null) {</span>
<span class="fc bfc" id="L1027" title="All 2 branches covered.">      for (ComponentPosition position : statsPositionList) {</span>
<span class="fc" id="L1028">        position.dataCollector.initNewList(1);</span>
        Integer tmpValue;
<span class="fc" id="L1030">        long[] values = new long[docSet.size()];</span>
        int value;
<span class="fc" id="L1032">        int number = 0;</span>
<span class="fc bfc" id="L1033" title="All 2 branches covered.">        for (int docId : docSet) {</span>
<span class="fc" id="L1034">          tmpValue = positionsData.get(docId);</span>
<span class="pc bpc" id="L1035" title="1 of 2 branches missed.">          value = tmpValue == null ? 0 : tmpValue.intValue();</span>
<span class="fc bfc" id="L1036" title="All 2 branches covered.">          if (((position.minimumLong == null)</span>
<span class="fc bfc" id="L1037" title="All 4 branches covered.">              || (value &gt;= position.minimumLong))</span>
              &amp;&amp; ((position.maximumLong == null)
<span class="fc bfc" id="L1039" title="All 2 branches covered.">                  || (value &lt;= position.maximumLong))) {</span>
<span class="fc" id="L1040">            values[number] = value;</span>
<span class="fc" id="L1041">            number++;</span>
          }
<span class="fc" id="L1043">        }</span>
<span class="fc bfc" id="L1044" title="All 2 branches covered.">        if (number &gt; 0) {</span>
<span class="fc" id="L1045">          position.dataCollector.add(values, number);</span>
        }
<span class="fc" id="L1047">        position.dataCollector.closeNewList();</span>
<span class="fc" id="L1048">      }</span>
    }
<span class="fc" id="L1050">  }</span>

  /**
   * Creates the tokens.
   *
   * @param statsTokenList the stats token list
   * @param tokensData the tokens data
   * @param docSet the doc set
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createTokens(List&lt;ComponentToken&gt; statsTokenList,
      Map&lt;Integer, Integer&gt; tokensData, List&lt;Integer&gt; docSet)
      throws IOException {
<span class="pc bpc" id="L1063" title="1 of 2 branches missed.">    if (statsTokenList != null) {</span>
<span class="fc bfc" id="L1064" title="All 2 branches covered.">      for (ComponentToken token : statsTokenList) {</span>
<span class="fc" id="L1065">        token.dataCollector.initNewList(1);</span>
        Integer tmpValue;
<span class="fc" id="L1067">        long[] values = new long[docSet.size()];</span>
        int value;
<span class="fc" id="L1069">        int number = 0;</span>
<span class="pc bpc" id="L1070" title="1 of 2 branches missed.">        if (tokensData != null) {</span>
<span class="fc bfc" id="L1071" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="fc" id="L1072">            tmpValue = tokensData.get(docId);</span>
<span class="pc bpc" id="L1073" title="1 of 2 branches missed.">            value = tmpValue == null ? 0 : tmpValue.intValue();</span>
<span class="pc bpc" id="L1074" title="1 of 6 branches missed.">            if (((token.minimumLong == null) || (value &gt;= token.minimumLong))</span>
                &amp;&amp; ((token.maximumLong == null)
<span class="pc bpc" id="L1076" title="1 of 2 branches missed.">                    || (value &lt;= token.maximumLong))) {</span>
<span class="fc" id="L1077">              values[number] = value;</span>
<span class="fc" id="L1078">              number++;</span>
            }
<span class="fc" id="L1080">          }</span>
        }
<span class="fc bfc" id="L1082" title="All 2 branches covered.">        if (number &gt; 0) {</span>
<span class="fc" id="L1083">          token.dataCollector.add(values, number);</span>
        }
<span class="fc" id="L1085">        token.dataCollector.closeNewList();</span>
<span class="fc" id="L1086">      }</span>
    }
<span class="fc" id="L1088">  }</span>

  /**
   * Creates the stats.
   *
   * @param statsSpanList the stats span list
   * @param positionsData the positions data
   * @param spansNumberData the spans number data
   * @param docSet the doc set
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createStats(List&lt;ComponentSpan&gt; statsSpanList,
      Map&lt;Integer, Integer&gt; positionsData,
      Map&lt;MtasSpanQuery, Map&lt;Integer, Integer&gt;&gt; spansNumberData,
      Integer[] docSet) throws IOException {
<span class="pc bpc" id="L1103" title="1 of 2 branches missed.">    if (statsSpanList != null) {</span>
<span class="fc bfc" id="L1104" title="All 2 branches covered.">      for (ComponentSpan span : statsSpanList) {</span>
<span class="pc bpc" id="L1105" title="1 of 2 branches missed.">        if (span.parser.needArgumentsNumber() &gt; span.queries.length) {</span>
<span class="nc" id="L1106">          throw new IOException(</span>
              &quot;function &quot; + span.parser + &quot; expects (at least) &quot;
<span class="nc" id="L1108">                  + span.parser.needArgumentsNumber() + &quot; queries&quot;);</span>
        }
        // collect
<span class="fc" id="L1111">        Map&lt;Integer, long[]&gt; args = computeArguments(spansNumberData,</span>
            span.queries, docSet);
<span class="pc bpc" id="L1113" title="1 of 2 branches missed.">        if (span.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
          // try to call functionParser as little as possible
<span class="pc bpc" id="L1115" title="2 of 8 branches missed.">          if (span.statsType.equals(CodecUtil.STATS_BASIC)</span>
              &amp;&amp; (span.minimumLong == null) &amp;&amp; (span.maximumLong == null)
              &amp;&amp; (span.functions == null
<span class="pc bpc" id="L1118" title="2 of 4 branches missed.">                  || (span.functionBasic() &amp;&amp; span.functionSumRule()</span>
<span class="pc bpc" id="L1119" title="1 of 2 branches missed.">                      &amp;&amp; !span.functionNeedPositions()))) {</span>
            // initialise
<span class="fc" id="L1121">            int length = span.parser.needArgumentsNumber();</span>
<span class="fc" id="L1122">            long[] valueSum = new long[length];</span>
<span class="fc" id="L1123">            long valuePositions = 0;</span>
            // collect
<span class="pc bpc" id="L1125" title="1 of 2 branches missed.">            if (docSet.length &gt; 0) {</span>
              long[] tmpArgs;
<span class="fc bfc" id="L1127" title="All 2 branches covered.">              for (int docId : docSet) {</span>
<span class="fc" id="L1128">                tmpArgs = args.get(docId);</span>
<span class="fc bfc" id="L1129" title="All 2 branches covered.">                valuePositions += (positionsData == null) ? 0</span>
<span class="fc" id="L1130">                    : positionsData.get(docId);</span>
<span class="pc bpc" id="L1131" title="1 of 2 branches missed.">                if (tmpArgs != null) {</span>
<span class="fc bfc" id="L1132" title="All 2 branches covered.">                  for (int i = 0; i &lt; length; i++) {</span>
<span class="fc" id="L1133">                    valueSum[i] += tmpArgs[i];</span>
                  }
                }
              }
              long valueLong;
<span class="fc" id="L1138">              span.dataCollector.initNewList(1);</span>
              try {
<span class="fc" id="L1140">                valueLong = span.parser.getValueLong(valueSum, valuePositions);</span>
<span class="fc" id="L1141">                span.dataCollector.add(valueLong, docSet.length);</span>
<span class="nc" id="L1142">              } catch (IOException e) {</span>
<span class="nc" id="L1143">                log.debug(e);</span>
<span class="nc" id="L1144">                span.dataCollector.error(e.getMessage());</span>
<span class="fc" id="L1145">              }</span>
<span class="pc bpc" id="L1146" title="1 of 2 branches missed.">              if (span.functions != null) {</span>
<span class="fc bfc" id="L1147" title="All 2 branches covered.">                for (SubComponentFunction function : span.functions) {</span>
<span class="fc" id="L1148">                  function.dataCollector.initNewList(1);</span>
<span class="pc bpc" id="L1149" title="1 of 2 branches missed.">                  if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                    try {
<span class="fc" id="L1151">                      valueLong = function.parserFunction.getValueLong(valueSum,</span>
                          valuePositions);
<span class="fc" id="L1153">                      function.dataCollector.add(valueLong, docSet.length);</span>
<span class="nc" id="L1154">                    } catch (IOException e) {</span>
<span class="nc" id="L1155">                      log.debug(e);</span>
<span class="nc" id="L1156">                      function.dataCollector.error(e.getMessage());</span>
<span class="pc" id="L1157">                    }</span>
<span class="nc" id="L1158">                  } else if (function.dataType</span>
<span class="nc bnc" id="L1159" title="All 2 branches missed.">                      .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
                    try {
<span class="nc" id="L1161">                      double valueDouble = function.parserFunction</span>
<span class="nc" id="L1162">                          .getValueDouble(valueSum, valuePositions);</span>
<span class="nc" id="L1163">                      function.dataCollector.add(valueDouble, docSet.length);</span>
<span class="nc" id="L1164">                    } catch (IOException e) {</span>
<span class="nc" id="L1165">                      log.debug(e);</span>
<span class="nc" id="L1166">                      function.dataCollector.error(e.getMessage());</span>
<span class="nc" id="L1167">                    }</span>
                  } else {
<span class="nc" id="L1169">                    throw new IOException(</span>
                        &quot;can't handle function dataType &quot; + function.dataType);
                  }
<span class="fc" id="L1172">                  function.dataCollector.closeNewList();</span>
<span class="fc" id="L1173">                }</span>
              }
<span class="fc" id="L1175">              span.dataCollector.closeNewList();</span>
            }
<span class="fc" id="L1177">          } else {</span>
            // collect
<span class="pc bpc" id="L1179" title="1 of 2 branches missed.">            if (docSet.length &gt; 0) {</span>
<span class="fc" id="L1180">              int number = 0;</span>
              int positions;
              long valueLong;
              double valueDouble;
<span class="fc" id="L1184">              long[] values = new long[docSet.length];</span>
<span class="fc" id="L1185">              long[][] functionValuesLong = null;</span>
<span class="fc" id="L1186">              double[][] functionValuesDouble = null;</span>
<span class="fc" id="L1187">              span.dataCollector.initNewList(1);</span>
<span class="pc bpc" id="L1188" title="1 of 2 branches missed.">              if (span.functions != null) {</span>
<span class="fc" id="L1189">                functionValuesLong = new long[span.functions.size()][];</span>
<span class="fc" id="L1190">                functionValuesDouble = new double[span.functions.size()][];</span>
<span class="pc bpc" id="L1191" title="1 of 2 branches missed.">                for (int i = 0; i &lt; span.functions.size(); i++) {</span>
<span class="nc" id="L1192">                  SubComponentFunction function = span.functions.get(i);</span>
<span class="nc bnc" id="L1193" title="All 2 branches missed.">                  if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L1194">                    functionValuesLong[i] = new long[docSet.length];</span>
<span class="nc" id="L1195">                    functionValuesDouble[i] = null;</span>
<span class="nc" id="L1196">                  } else if (function.dataType</span>
<span class="nc bnc" id="L1197" title="All 2 branches missed.">                      .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L1198">                    functionValuesLong[i] = null;</span>
<span class="nc" id="L1199">                    functionValuesDouble[i] = new double[docSet.length];</span>
                  }
<span class="nc" id="L1201">                  function.dataCollector.initNewList(1);</span>
                }
              }
<span class="fc bfc" id="L1204" title="All 2 branches covered.">              for (int docId : docSet) {</span>
<span class="fc bfc" id="L1205" title="All 2 branches covered.">                if (positionsData == null) {</span>
<span class="fc" id="L1206">                  positions = 0;</span>
                } else {
<span class="pc bpc" id="L1208" title="1 of 2 branches missed.">                  positions = (positionsData.get(docId) == null ? 0</span>
<span class="fc" id="L1209">                      : positionsData.get(docId));</span>
                }
<span class="fc" id="L1211">                valueLong = span.parser.getValueLong(args.get(docId),</span>
                    positions);
<span class="fc bfc" id="L1213" title="All 2 branches covered.">                if (((span.minimumLong == null)</span>
<span class="fc bfc" id="L1214" title="All 4 branches covered.">                    || (valueLong &gt;= span.minimumLong))</span>
                    &amp;&amp; ((span.maximumLong == null)
<span class="fc bfc" id="L1216" title="All 2 branches covered.">                        || (valueLong &lt;= span.maximumLong))) {</span>
<span class="fc" id="L1217">                  values[number] = valueLong;</span>
<span class="pc bpc" id="L1218" title="1 of 2 branches missed.">                  if (span.functions != null) {</span>
<span class="pc bpc" id="L1219" title="1 of 2 branches missed.">                    for (int i = 0; i &lt; span.functions.size(); i++) {</span>
<span class="nc" id="L1220">                      SubComponentFunction function = span.functions.get(i);</span>
                      try {
<span class="nc" id="L1222">                        if (function.dataType</span>
<span class="nc bnc" id="L1223" title="All 2 branches missed.">                            .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L1224">                          valueLong = function.parserFunction</span>
<span class="nc" id="L1225">                              .getValueLong(args.get(docId), positions);</span>
<span class="nc" id="L1226">                          functionValuesLong[i][number] = valueLong;</span>
<span class="nc" id="L1227">                        } else if (function.dataType</span>
<span class="nc bnc" id="L1228" title="All 2 branches missed.">                            .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L1229">                          valueDouble = function.parserFunction</span>
<span class="nc" id="L1230">                              .getValueDouble(args.get(docId), positions);</span>
<span class="nc" id="L1231">                          functionValuesDouble[i][number] = valueDouble;</span>
                        }
<span class="nc" id="L1233">                      } catch (IOException e) {</span>
<span class="nc" id="L1234">                        log.debug(e);</span>
<span class="nc" id="L1235">                        function.dataCollector.error(e.getMessage());</span>
<span class="nc" id="L1236">                      }</span>
                    }
                  }
<span class="fc" id="L1239">                  number++;</span>
                }
              }
<span class="fc bfc" id="L1242" title="All 2 branches covered.">              if (number &gt; 0) {</span>
<span class="fc" id="L1243">                span.dataCollector.add(values, number);</span>
<span class="pc bpc" id="L1244" title="1 of 2 branches missed.">                if (span.functions != null) {</span>
<span class="pc bpc" id="L1245" title="1 of 2 branches missed.">                  for (int i = 0; i &lt; span.functions.size(); i++) {</span>
<span class="nc" id="L1246">                    SubComponentFunction function = span.functions.get(i);</span>
<span class="nc bnc" id="L1247" title="All 2 branches missed.">                    if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L1248">                      function.dataCollector.add(functionValuesLong[i], number);</span>
<span class="nc" id="L1249">                    } else if (function.dataType</span>
<span class="nc bnc" id="L1250" title="All 2 branches missed.">                        .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L1251">                      function.dataCollector.add(functionValuesDouble[i],</span>
                          number);
                    }
                  }
                }
              }
<span class="fc" id="L1257">              span.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L1258" title="1 of 2 branches missed.">              if (span.functions != null) {</span>
<span class="pc bpc" id="L1259" title="1 of 2 branches missed.">                for (SubComponentFunction function : span.functions) {</span>
<span class="nc" id="L1260">                  function.dataCollector.closeNewList();</span>
<span class="nc" id="L1261">                }</span>
              }
<span class="fc" id="L1263">            }</span>
          }
        } else {
<span class="nc" id="L1266">          throw new IOException(&quot;unexpected dataType &quot; + span.dataType);</span>
        }
<span class="fc" id="L1268">      }</span>
    }
<span class="fc" id="L1270">  }</span>

  /**
   * Creates the list.
   *
   * @param listList the list list
   * @param spansNumberData the spans number data
   * @param spansMatchData the spans match data
   * @param docSet the doc set
   * @param field the field
   * @param docBase the doc base
   * @param uniqueKeyField the unique key field
   * @param mtasCodecInfo the mtas codec info
   * @param searcher the searcher
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createList(List&lt;ComponentList&gt; listList,
      Map&lt;MtasSpanQuery, Map&lt;Integer, Integer&gt;&gt; spansNumberData,
      Map&lt;MtasSpanQuery, Map&lt;Integer, List&lt;Match&gt;&gt;&gt; spansMatchData,
      List&lt;Integer&gt; docSet, String field, int docBase, String uniqueKeyField,
      CodecInfo mtasCodecInfo, IndexSearcher searcher) throws IOException {
<span class="nc bnc" id="L1291" title="All 2 branches missed.">    if (listList != null) {</span>
<span class="nc bnc" id="L1292" title="All 2 branches missed.">      for (ComponentList list : listList) {</span>
        // collect not only stats
<span class="nc bnc" id="L1294" title="All 2 branches missed.">        if (list.number &gt; 0) {</span>
<span class="nc" id="L1295">          Map&lt;Integer, List&lt;Match&gt;&gt; matchData = spansMatchData</span>
<span class="nc" id="L1296">              .get(list.spanQuery);</span>
<span class="nc" id="L1297">          Map&lt;Integer, Integer&gt; numberData = spansNumberData</span>
<span class="nc" id="L1298">              .get(list.spanQuery);</span>
          List&lt;Match&gt; matchList;
          Integer matchNumber;
<span class="nc bnc" id="L1301" title="All 2 branches missed.">          if (list.output.equals(ComponentList.LIST_OUTPUT_HIT)) {</span>
<span class="nc bnc" id="L1302" title="All 2 branches missed.">            for (int docId : docSet) {</span>
<span class="nc bnc" id="L1303" title="All 2 branches missed.">              if (matchData != null</span>
<span class="nc bnc" id="L1304" title="All 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
<span class="nc bnc" id="L1305" title="All 2 branches missed.">                if (list.position &lt; (list.start + list.number)) {</span>
<span class="nc" id="L1306">                  boolean getDoc = false;</span>
                  Match m;
<span class="nc bnc" id="L1308" title="All 2 branches missed.">                  for (int i = 0; i &lt; matchList.size(); i++) {</span>
<span class="nc bnc" id="L1309" title="All 4 branches missed.">                    if ((list.position &gt;= list.start)</span>
                        &amp;&amp; (list.position &lt; (list.start + list.number))) {
<span class="nc" id="L1311">                      m = matchList.get(i);</span>
<span class="nc" id="L1312">                      getDoc = true;</span>
<span class="nc" id="L1313">                      int startPosition = m.startPosition;</span>
<span class="nc" id="L1314">                      int endPosition = m.endPosition - 1;</span>
<span class="nc" id="L1315">                      List&lt;MtasTreeHit&lt;String&gt;&gt; terms = mtasCodecInfo</span>
<span class="nc" id="L1316">                          .getPositionedTermsByPrefixesAndPositionRange(field,</span>
                              (docId - docBase), list.prefixes,
                              startPosition - list.left,
                              endPosition + list.right);
                      // construct hit
<span class="nc" id="L1321">                      Map&lt;Integer, List&lt;String&gt;&gt; kwicListHits = new HashMap&lt;&gt;();</span>
<span class="nc" id="L1322">                      for (int position = Math.max(0,</span>
<span class="nc bnc" id="L1323" title="All 2 branches missed.">                          startPosition - list.left); position &lt;= (endPosition</span>
<span class="nc" id="L1324">                              + list.right); position++) {</span>
<span class="nc" id="L1325">                        kwicListHits.put(position, new ArrayList&lt;String&gt;());</span>
                      }
                      List&lt;String&gt; termList;
<span class="nc bnc" id="L1328" title="All 2 branches missed.">                      for (MtasTreeHit&lt;String&gt; term : terms) {</span>
<span class="nc" id="L1329">                        for (int position = Math.max(</span>
                            (startPosition - list.left),
<span class="nc bnc" id="L1331" title="All 2 branches missed.">                            term.startPosition); position &lt;= Math.min(</span>
                                (endPosition + list.right),
<span class="nc" id="L1333">                                term.endPosition); position++) {</span>
<span class="nc" id="L1334">                          termList = kwicListHits.get(position);</span>
<span class="nc" id="L1335">                          termList.add(term.data);</span>
                        }
<span class="nc" id="L1337">                      }</span>
<span class="nc" id="L1338">                      list.hits.add(new ListHit(docId, i, m, kwicListHits));</span>
                    }
<span class="nc" id="L1340">                    list.position++;</span>
                  }
<span class="nc bnc" id="L1342" title="All 2 branches missed.">                  if (getDoc) {</span>
                    // get unique id
<span class="nc" id="L1344">                    Document doc = searcher.doc(docId,</span>
<span class="nc" id="L1345">                        new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L1346">                    IndexableField indxfld = doc.getField(uniqueKeyField);</span>
                    // get other doc info
<span class="nc bnc" id="L1348" title="All 2 branches missed.">                    if (indxfld != null) {</span>
<span class="nc" id="L1349">                      list.uniqueKey.put(docId, indxfld.stringValue());</span>
                    }
<span class="nc" id="L1351">                    list.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L1352">                    IndexDoc mDoc = mtasCodecInfo.getDoc(field,</span>
                        (docId - docBase));
<span class="nc bnc" id="L1354" title="All 2 branches missed.">                    if (mDoc != null) {</span>
<span class="nc" id="L1355">                      list.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L1356">                      list.maxPosition.put(docId, mDoc.maxPosition);</span>
                    }
                  }
<span class="nc" id="L1359">                } else {</span>
<span class="nc" id="L1360">                  list.position += matchList.size();</span>
                }
<span class="nc bnc" id="L1362" title="All 2 branches missed.">              } else if (numberData != null</span>
<span class="nc bnc" id="L1363" title="All 2 branches missed.">                  &amp;&amp; (matchNumber = numberData.get(docId)) != null) {</span>
<span class="nc" id="L1364">                list.position += matchNumber;</span>
              }
<span class="nc" id="L1366">            }</span>
<span class="nc" id="L1367">            list.total = list.position;</span>
<span class="nc bnc" id="L1368" title="All 2 branches missed.">          } else if (list.output.equals(ComponentList.LIST_OUTPUT_TOKEN)) {</span>
<span class="nc bnc" id="L1369" title="All 2 branches missed.">            for (int docId : docSet) {</span>
<span class="nc bnc" id="L1370" title="All 2 branches missed.">              if (matchData != null</span>
<span class="nc bnc" id="L1371" title="All 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
<span class="nc bnc" id="L1372" title="All 2 branches missed.">                if (list.position &lt; (list.start + list.number)) {</span>
<span class="nc" id="L1373">                  boolean getDoc = false;</span>
                  Match m;
<span class="nc bnc" id="L1375" title="All 2 branches missed.">                  for (int i = 0; i &lt; matchList.size(); i++) {</span>
<span class="nc bnc" id="L1376" title="All 4 branches missed.">                    if ((list.position &gt;= list.start)</span>
                        &amp;&amp; (list.position &lt; (list.start + list.number))) {
<span class="nc" id="L1378">                      m = matchList.get(i);</span>
<span class="nc" id="L1379">                      getDoc = true;</span>
<span class="nc" id="L1380">                      int startPosition = m.startPosition;</span>
<span class="nc" id="L1381">                      int endPosition = m.endPosition - 1;</span>
                      List&lt;MtasTokenString&gt; tokens;
<span class="nc" id="L1383">                      tokens = mtasCodecInfo</span>
<span class="nc" id="L1384">                          .getPrefixFilteredObjectsByPositions(field,</span>
                              (docId - docBase), list.prefixes,
                              startPosition - list.left,
                              endPosition + list.right);
<span class="nc" id="L1388">                      list.tokens.add(new ListToken(docId, i, m, tokens));</span>
                    }
<span class="nc" id="L1390">                    list.position++;</span>
                  }
<span class="nc bnc" id="L1392" title="All 2 branches missed.">                  if (getDoc) {</span>
                    // get unique id
<span class="nc" id="L1394">                    Document doc = searcher.doc(docId,</span>
<span class="nc" id="L1395">                        new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L1396">                    IndexableField indxfld = doc.getField(uniqueKeyField);</span>
                    // get other doc info
<span class="nc bnc" id="L1398" title="All 2 branches missed.">                    if (indxfld != null) {</span>
<span class="nc" id="L1399">                      list.uniqueKey.put(docId, indxfld.stringValue());</span>
                    }
<span class="nc" id="L1401">                    list.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L1402">                    IndexDoc mDoc = mtasCodecInfo.getDoc(field,</span>
                        (docId - docBase));
<span class="nc bnc" id="L1404" title="All 2 branches missed.">                    if (mDoc != null) {</span>
<span class="nc" id="L1405">                      list.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L1406">                      list.maxPosition.put(docId, mDoc.maxPosition);</span>
                    }
                  }
<span class="nc" id="L1409">                } else {</span>
<span class="nc" id="L1410">                  list.position += matchList.size();</span>
                }
<span class="nc bnc" id="L1412" title="All 2 branches missed.">              } else if (numberData != null</span>
<span class="nc bnc" id="L1413" title="All 2 branches missed.">                  &amp;&amp; (matchNumber = numberData.get(docId)) != null) {</span>
<span class="nc" id="L1414">                list.position += matchNumber;</span>
              }
<span class="nc" id="L1416">            }</span>
<span class="nc" id="L1417">            list.total = list.position;</span>
          }

<span class="nc" id="L1420">        } else {</span>
<span class="nc" id="L1421">          Map&lt;Integer, Integer&gt; data = spansNumberData.get(list.spanQuery);</span>
<span class="nc bnc" id="L1422" title="All 2 branches missed.">          if (data != null) {</span>
<span class="nc bnc" id="L1423" title="All 2 branches missed.">            for (int docId : docSet) {</span>
<span class="nc" id="L1424">              Integer matchNumber = data.get(docId);</span>
<span class="nc bnc" id="L1425" title="All 2 branches missed.">              if (matchNumber != null) {</span>
<span class="nc" id="L1426">                list.position += matchNumber;</span>
              }
<span class="nc" id="L1428">            }</span>
<span class="nc" id="L1429">            list.total = list.position;</span>
          }
        }
<span class="nc" id="L1432">      }</span>
    }
<span class="nc" id="L1434">  }</span>

  /**
   * Creates the group.
   *
   * @param groupList the group list
   * @param spansMatchData the spans match data
   * @param docSet the doc set
   * @param fieldInfo the field info
   * @param field the field
   * @param docBase the doc base
   * @param mtasCodecInfo the mtas codec info
   * @param searcher the searcher
   * @param lrc the lrc
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createGroup(List&lt;ComponentGroup&gt; groupList,
      Map&lt;MtasSpanQuery, Map&lt;Integer, List&lt;Match&gt;&gt;&gt; spansMatchData,
      List&lt;Integer&gt; docSet, FieldInfo fieldInfo, String field, int docBase,
      CodecInfo mtasCodecInfo, IndexSearcher searcher, LeafReaderContext lrc)
      throws IOException {

<span class="pc bpc" id="L1456" title="2 of 4 branches missed.">    if (mtasCodecInfo != null &amp;&amp; groupList != null) {</span>
      List&lt;Match&gt; matchList;
      Map&lt;Integer, List&lt;Match&gt;&gt; matchData;
<span class="fc bfc" id="L1459" title="All 2 branches covered.">      for (ComponentGroup group : groupList) {</span>
<span class="fc" id="L1460">        group.dataCollector.setWithTotal();</span>
<span class="pc bpc" id="L1461" title="1 of 2 branches missed.">        if (!group.prefixes.isEmpty()) {</span>
<span class="fc" id="L1462">          matchData = spansMatchData.get(group.spanQuery);</span>
<span class="fc" id="L1463">          Set&lt;String&gt; knownPrefixes = collectKnownPrefixes(fieldInfo);</span>
<span class="fc" id="L1464">          Set&lt;String&gt; intersectionPrefixes = collectIntersectionPrefixes(</span>
              fieldInfo);
<span class="fc" id="L1466">          boolean intersectionGroupPrefixes = intersectionPrefixes(group,</span>
              intersectionPrefixes);
<span class="fc" id="L1468">          boolean availablePrefixes = availablePrefixes(group, knownPrefixes);</span>
          // sort match lists
<span class="pc bpc" id="L1470" title="1 of 2 branches missed.">          if (!intersectionGroupPrefixes) {</span>
<span class="fc bfc" id="L1471" title="All 2 branches covered.">            for (Entry&lt;Integer, List&lt;Match&gt;&gt; entry : matchData.entrySet()) {</span>
<span class="fc" id="L1472">              sortMatchList(entry.getValue());</span>
<span class="fc" id="L1473">            }</span>
          }
          // init
<span class="fc" id="L1476">          group.dataCollector.initNewList(1);</span>
          int docId;

<span class="fc" id="L1479">          Map&lt;GroupHit, Long&gt; occurencesSum = new HashMap&lt;&gt;();</span>
<span class="fc" id="L1480">          Map&lt;GroupHit, Integer&gt; occurencesN = new HashMap&lt;&gt;();</span>
<span class="fc" id="L1481">          Set&lt;GroupHit&gt; occurencesInCurrentDocument = new HashSet&lt;&gt;();</span>

<span class="pc bpc" id="L1483" title="1 of 2 branches missed.">          if (!availablePrefixes) {</span>
<span class="nc" id="L1484">            HashMap&lt;Integer, GroupHit&gt; hits = new HashMap&lt;&gt;();</span>
<span class="nc bnc" id="L1485" title="All 2 branches missed.">            for (int docCounter = 0; docCounter &lt; docSet.size(); docCounter++) {</span>
<span class="nc" id="L1486">              occurencesInCurrentDocument.clear();</span>
<span class="nc" id="L1487">              docId = docSet.get(docCounter);</span>
              GroupHit hit;
              GroupHit hitKey;
<span class="nc bnc" id="L1490" title="All 2 branches missed.">              if (matchData != null</span>
<span class="nc bnc" id="L1491" title="All 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null</span>
<span class="nc bnc" id="L1492" title="All 2 branches missed.">                  &amp;&amp; !matchList.isEmpty()) {</span>
<span class="nc" id="L1493">                Iterator&lt;Match&gt; it = matchList.listIterator();</span>
<span class="nc bnc" id="L1494" title="All 2 branches missed.">                while (it.hasNext()) {</span>
<span class="nc" id="L1495">                  Match m = it.next();</span>
<span class="nc" id="L1496">                  IntervalTreeNodeData&lt;String&gt; positionHit = createPositionHit(</span>
                      m, group);
<span class="nc" id="L1498">                  int length = m.endPosition - m.startPosition;</span>
<span class="nc" id="L1499">                  hitKey = null;</span>
<span class="nc bnc" id="L1500" title="All 2 branches missed.">                  if (!hits.containsKey(length)) {</span>
<span class="nc" id="L1501">                    hit = new GroupHit(positionHit.list, positionHit.start,</span>
                        positionHit.end, positionHit.hitStart,
                        positionHit.hitEnd, group, knownPrefixes);
<span class="nc" id="L1504">                    hits.put(length, hit);</span>
                  } else {
<span class="nc" id="L1506">                    hit = hits.get(length);</span>
<span class="nc bnc" id="L1507" title="All 2 branches missed.">                    for (GroupHit hitKeyItem : occurencesSum.keySet()) {</span>
<span class="nc bnc" id="L1508" title="All 2 branches missed.">                      if (hitKeyItem.equals(hit)) {</span>
<span class="nc" id="L1509">                        hitKey = hitKeyItem;</span>
<span class="nc" id="L1510">                        break;</span>
                      }
<span class="nc" id="L1512">                    }</span>
                  }
<span class="nc bnc" id="L1514" title="All 2 branches missed.">                  if (hitKey == null) {</span>
<span class="nc" id="L1515">                    occurencesSum.put(hit, Long.valueOf(1));</span>
<span class="nc" id="L1516">                    occurencesN.put(hit, 1);</span>
<span class="nc" id="L1517">                    occurencesInCurrentDocument.add(hit);</span>
                  } else {
<span class="nc" id="L1519">                    occurencesSum.put(hitKey, occurencesSum.get(hitKey) + 1);</span>
<span class="nc bnc" id="L1520" title="All 2 branches missed.">                    if (!occurencesInCurrentDocument.contains(hitKey)) {</span>
<span class="nc bnc" id="L1521" title="All 2 branches missed.">                      if (occurencesN.containsKey(hitKey)) {</span>
<span class="nc" id="L1522">                        occurencesN.put(hitKey, occurencesN.get(hitKey) + 1);</span>
                      } else {
<span class="nc" id="L1524">                        occurencesN.put(hitKey, 1);</span>
                      }
<span class="nc" id="L1526">                      occurencesInCurrentDocument.add(hitKey);</span>
                    }
                  }
<span class="nc" id="L1529">                }</span>
              }
            }
<span class="nc" id="L1532">          } else {</span>
<span class="fc" id="L1533">            int maximumNumberOfDocuments = 0;</span>
<span class="fc" id="L1534">            int boundaryMinimumNumberOfDocuments = 1;</span>
<span class="fc" id="L1535">            int boundaryMaximumNumberOfDocuments = 5;</span>
<span class="fc" id="L1536">            Set&lt;GroupHit&gt; administrationOccurrences = new HashSet&lt;&gt;();</span>
<span class="fc bfc" id="L1537" title="All 2 branches covered.">            for (int docCounter = 0; docCounter &lt; docSet.size(); docCounter++) {</span>
<span class="fc" id="L1538">              occurencesInCurrentDocument.clear();</span>
<span class="fc" id="L1539">              docId = docSet.get(docCounter);</span>
<span class="pc bpc" id="L1540" title="1 of 2 branches missed.">              if (matchData != null</span>
<span class="pc bpc" id="L1541" title="1 of 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null</span>
<span class="pc bpc" id="L1542" title="1 of 2 branches missed.">                  &amp;&amp; !matchList.isEmpty()) {</span>
                // loop over matches
<span class="fc" id="L1544">                Iterator&lt;Match&gt; it = matchList.listIterator();</span>
<span class="fc" id="L1545">                ArrayList&lt;IntervalTreeNodeData&lt;String&gt;&gt; positionsHits = new ArrayList&lt;&gt;();</span>
<span class="fc bfc" id="L1546" title="All 2 branches covered.">                while (it.hasNext()) {</span>
<span class="fc" id="L1547">                  Match m = it.next();</span>
<span class="fc" id="L1548">                  positionsHits.add(createPositionHit(m, group));</span>
<span class="fc" id="L1549">                }</span>
<span class="fc" id="L1550">                mtasCodecInfo.collectTermsByPrefixesForListOfHitPositions(field,</span>
                    (docId - docBase), group.prefixes, positionsHits);
                // administration
<span class="fc bfc" id="L1553" title="All 2 branches covered.">                for (IntervalTreeNodeData&lt;String&gt; positionHit : positionsHits) {</span>
<span class="fc" id="L1554">                  GroupHit hit = new GroupHit(positionHit.list,</span>
                      positionHit.start, positionHit.end, positionHit.hitStart,
                      positionHit.hitEnd, group, knownPrefixes);
<span class="fc" id="L1557">                  GroupHit hitKey = null;</span>
<span class="fc bfc" id="L1558" title="All 2 branches covered.">                  for (GroupHit hitKeyItem : occurencesSum.keySet()) {</span>
<span class="fc bfc" id="L1559" title="All 2 branches covered.">                    if (hitKeyItem.equals(hit)) {</span>
<span class="fc" id="L1560">                      hitKey = hitKeyItem;</span>
<span class="fc" id="L1561">                      break;</span>
                    }
<span class="fc" id="L1563">                  }</span>
<span class="fc bfc" id="L1564" title="All 2 branches covered.">                  if (hitKey == null) {</span>
<span class="fc" id="L1565">                    occurencesSum.put(hit, Long.valueOf(1));</span>
<span class="fc" id="L1566">                    occurencesN.put(hit, 1);</span>
<span class="fc" id="L1567">                    occurencesInCurrentDocument.add(hit);</span>
                  } else {
<span class="fc" id="L1569">                    occurencesSum.put(hitKey, occurencesSum.get(hitKey) + 1);</span>
<span class="pc bpc" id="L1570" title="1 of 2 branches missed.">                    if (!occurencesInCurrentDocument.contains(hitKey)) {</span>
<span class="nc bnc" id="L1571" title="All 2 branches missed.">                      if (occurencesN.containsKey(hitKey)) {</span>
<span class="nc" id="L1572">                        occurencesN.put(hitKey, occurencesN.get(hitKey) + 1);</span>
                      } else {
<span class="nc" id="L1574">                        occurencesN.put(hitKey, 1);</span>
                      }
<span class="nc" id="L1576">                      occurencesInCurrentDocument.add(hitKey);</span>
                    }
                  }
<span class="fc" id="L1579">                }</span>
<span class="pc bpc" id="L1580" title="1 of 2 branches missed.">                if (!intersectionGroupPrefixes) {</span>
<span class="fc bfc" id="L1581" title="All 2 branches covered.">                  for (GroupHit groupHit : occurencesInCurrentDocument) {</span>
<span class="fc" id="L1582">                    int tmpNumber = occurencesN.get(groupHit);</span>
<span class="fc" id="L1583">                    maximumNumberOfDocuments = Math</span>
<span class="fc" id="L1584">                        .max(maximumNumberOfDocuments, tmpNumber);</span>
<span class="pc bpc" id="L1585" title="1 of 2 branches missed.">                    if (tmpNumber &gt; boundaryMinimumNumberOfDocuments) {</span>
<span class="nc" id="L1586">                      administrationOccurrences.add(groupHit);</span>
                    }
<span class="fc" id="L1588">                  }</span>
                  // collect spans
<span class="pc bpc" id="L1590" title="1 of 2 branches missed.">                  if (maximumNumberOfDocuments &gt; boundaryMaximumNumberOfDocuments) {</span>
<span class="nc bnc" id="L1591" title="All 2 branches missed.">                    if (!administrationOccurrences.isEmpty()) {</span>
<span class="nc" id="L1592">                      Map&lt;GroupHit, Spans&gt; list = collectSpansForOccurences(</span>
                          administrationOccurrences, knownPrefixes, field,
                          searcher, lrc);
<span class="nc bnc" id="L1595" title="All 2 branches missed.">                      if (list.size() &gt; 0) {</span>
<span class="nc" id="L1596">                        collectGroupUsingSpans(list, docSet, docBase,</span>
                            docCounter, matchData, occurencesSum, occurencesN);
                      }
                    }
<span class="nc" id="L1600">                    administrationOccurrences.clear();</span>
<span class="nc" id="L1601">                    maximumNumberOfDocuments = 0;</span>
<span class="nc" id="L1602">                    boundaryMinimumNumberOfDocuments = (int) Math</span>
<span class="nc" id="L1603">                        .ceil(boundaryMinimumNumberOfDocuments * 1.2);</span>
<span class="nc" id="L1604">                    boundaryMaximumNumberOfDocuments = (int) Math</span>
<span class="nc" id="L1605">                        .ceil(boundaryMaximumNumberOfDocuments * 1.2);</span>
                  }
                }
              }
            }
          }

<span class="fc bfc" id="L1612" title="All 2 branches covered.">          for (Entry&lt;GroupHit, Long&gt; entry : occurencesSum.entrySet()) {</span>
<span class="fc" id="L1613">            group.dataCollector.add(entry.getKey().toString(), entry.getValue(),</span>
<span class="fc" id="L1614">                occurencesN.get(entry.getKey()));</span>
<span class="fc" id="L1615">          }</span>
<span class="fc" id="L1616">          group.dataCollector.closeNewList();</span>
        }
<span class="fc" id="L1618">      }</span>
    }
<span class="fc" id="L1620">  }</span>

  /**
   * Available prefixes.
   *
   * @param group the group
   * @param knownPrefixes the known prefixes
   * @return true, if successful
   */
  private static boolean availablePrefixes(ComponentGroup group,
      Set&lt;String&gt; knownPrefixes) {
<span class="pc bpc" id="L1631" title="1 of 2 branches missed.">    if (knownPrefixes != null) {</span>
<span class="pc bpc" id="L1632" title="1 of 2 branches missed.">      for (String prefix : group.prefixes) {</span>
<span class="pc bpc" id="L1633" title="1 of 2 branches missed.">        if (knownPrefixes.contains(prefix)) {</span>
<span class="fc" id="L1634">          return true;</span>
        }
<span class="nc" id="L1636">      }</span>
    }
<span class="nc" id="L1638">    return false;</span>
  }

  /**
   * Intersection prefixes.
   *
   * @param group the group
   * @param intersectionPrefixes the intersection prefixes
   * @return true, if successful
   */
  private static boolean intersectionPrefixes(ComponentGroup group,
      Set&lt;String&gt; intersectionPrefixes) {
<span class="pc bpc" id="L1650" title="1 of 2 branches missed.">    if (intersectionPrefixes != null) {</span>
<span class="fc bfc" id="L1651" title="All 2 branches covered.">      for (String prefix : group.prefixes) {</span>
<span class="pc bpc" id="L1652" title="1 of 2 branches missed.">        if (intersectionPrefixes.contains(prefix)) {</span>
<span class="nc" id="L1653">          return true;</span>
        }
<span class="fc" id="L1655">      }</span>
    }
<span class="fc" id="L1657">    return false;</span>
  }

  /**
   * Creates the position hit.
   *
   * @param m the m
   * @param group the group
   * @return the interval tree node data
   */
  private static IntervalTreeNodeData&lt;String&gt; createPositionHit(Match m,
      ComponentGroup group) {
<span class="fc" id="L1669">    Integer start = null;</span>
<span class="fc" id="L1670">    Integer end = null;</span>
<span class="pc bpc" id="L1671" title="5 of 6 branches missed.">    if (group.hitInside != null || group.hitInsideLeft != null</span>
        || group.hitInsideRight != null) {
<span class="fc" id="L1673">      start = m.startPosition;</span>
<span class="fc" id="L1674">      end = m.endPosition - 1;</span>
    } else {
<span class="nc" id="L1676">      start = null;</span>
<span class="nc" id="L1677">      end = null;</span>
    }
<span class="pc bpc" id="L1679" title="1 of 2 branches missed.">    if (group.hitLeft != null) {</span>
<span class="nc" id="L1680">      start = m.startPosition;</span>
<span class="nc" id="L1681">      end = Math.max(m.startPosition + group.hitLeft.length - 1,</span>
          m.endPosition - 1);
    }
<span class="pc bpc" id="L1684" title="1 of 2 branches missed.">    if (group.hitRight != null) {</span>
<span class="nc" id="L1685">      start = Math.min(m.endPosition - group.hitRight.length, m.startPosition);</span>
<span class="nc bnc" id="L1686" title="All 2 branches missed.">      end = end == null ? (m.endPosition - 1)</span>
<span class="nc" id="L1687">          : Math.max(end, (m.endPosition - 1));</span>
    }
<span class="pc bpc" id="L1689" title="1 of 2 branches missed.">    if (group.left != null) {</span>
<span class="nc bnc" id="L1690" title="All 2 branches missed.">      start = start == null ? m.startPosition - group.left.length</span>
<span class="nc" id="L1691">          : Math.min(m.startPosition - group.left.length, start);</span>
<span class="nc bnc" id="L1692" title="All 2 branches missed.">      end = end == null ? m.startPosition - 1</span>
<span class="nc" id="L1693">          : Math.max(m.startPosition - 1, end);</span>
    }
<span class="pc bpc" id="L1695" title="1 of 2 branches missed.">    if (group.right != null) {</span>
<span class="nc bnc" id="L1696" title="All 2 branches missed.">      start = start == null ? m.endPosition : Math.min(m.endPosition, start);</span>
<span class="nc bnc" id="L1697" title="All 2 branches missed.">      end = end == null ? m.endPosition + group.right.length - 1</span>
<span class="nc" id="L1698">          : Math.max(m.endPosition + group.right.length - 1, end);</span>
    }
<span class="fc" id="L1700">    return new IntervalTreeNodeData&lt;&gt;(start, end, m.startPosition,</span>
        m.endPosition - 1);
  }

  /**
   * Collect group using spans.
   *
   * @param list the list
   * @param docSet the doc set
   * @param docBase the doc base
   * @param docCounter the doc counter
   * @param matchData the match data
   * @param occurencesSum the occurences sum
   * @param occurencesN the occurences N
   * @return the int
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static int collectGroupUsingSpans(Map&lt;GroupHit, Spans&gt; list,
      List&lt;Integer&gt; docSet, int docBase, int docCounter,
      Map&lt;Integer, List&lt;Match&gt;&gt; matchData, Map&lt;GroupHit, Long&gt; occurencesSum,
      Map&lt;GroupHit, Integer&gt; occurencesN) throws IOException {
<span class="nc" id="L1721">    int total = 0;</span>
<span class="nc bnc" id="L1722" title="All 2 branches missed.">    if (docCounter + 1 &lt; docSet.size()) {</span>
      // initialize
<span class="nc" id="L1724">      int nextDocCounter = docCounter + 1;</span>
<span class="nc" id="L1725">      long[] subSum = new long[list.size()];</span>
<span class="nc" id="L1726">      int[] subN = new int[list.size()];</span>
<span class="nc" id="L1727">      boolean[] newNextDocs = new boolean[list.size()];</span>
      boolean newNextDoc;
<span class="nc" id="L1729">      int[] spansNextDoc = new int[list.size()];</span>
<span class="nc" id="L1730">      int nextDoc = 0;</span>
      List&lt;Match&gt; matchList;
<span class="nc" id="L1732">      GroupHit[] hitList = list.keySet().toArray(new GroupHit[list.size()]);</span>
<span class="nc" id="L1733">      Spans[] spansList = new Spans[list.size()];</span>
<span class="nc" id="L1734">      boolean[] finishedSpansList = new boolean[list.size()];</span>
<span class="nc" id="L1735">      newNextDoc = true;</span>
      // advance spans, find nextDoc
<span class="nc bnc" id="L1737" title="All 2 branches missed.">      for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc" id="L1738">        newNextDocs[i] = true;</span>
<span class="nc" id="L1739">        spansList[i] = list.get(hitList[i]);</span>
<span class="nc" id="L1740">        spansNextDoc[i] = spansList[i]</span>
<span class="nc" id="L1741">            .advance(docSet.get(nextDocCounter) - docBase);</span>
<span class="nc bnc" id="L1742" title="All 2 branches missed.">        nextDoc = (i == 0) ? spansNextDoc[i]</span>
<span class="nc" id="L1743">            : Math.min(nextDoc, spansNextDoc[i]);</span>
      }
      // loop over future documents
<span class="nc bnc" id="L1746" title="All 2 branches missed.">      while (nextDoc &lt; DocIdSetIterator.NO_MORE_DOCS) {</span>
        // find matches for next document
<span class="nc bnc" id="L1748" title="All 2 branches missed.">        while (nextDocCounter &lt; docSet.size()</span>
<span class="nc bnc" id="L1749" title="All 2 branches missed.">            &amp;&amp; docSet.get(nextDocCounter) &lt; (nextDoc + docBase)) {</span>
<span class="nc" id="L1750">          nextDocCounter++;</span>
        }
        // finish, if no more docs in set
<span class="nc bnc" id="L1753" title="All 2 branches missed.">        if (nextDocCounter &gt;= docSet.size()) {</span>
<span class="nc" id="L1754">          break;</span>
        }
        // go to the matches
<span class="nc bnc" id="L1757" title="All 2 branches missed.">        if (docSet.get(nextDocCounter) == nextDoc + docBase) {</span>
<span class="nc" id="L1758">          matchList = matchData.get(nextDoc + docBase);</span>
<span class="nc bnc" id="L1759" title="All 4 branches missed.">          if (matchList != null &amp;&amp; !matchList.isEmpty()) {</span>
            // initialize
<span class="nc" id="L1761">            int currentMatchPosition = 0;</span>
<span class="nc" id="L1762">            int lastMatchStartPosition = matchList</span>
<span class="nc" id="L1763">                .get(matchList.size() - 1).startPosition;</span>
<span class="nc" id="L1764">            ArrayList&lt;Match&gt; newMatchList = new ArrayList&lt;&gt;(matchList.size());</span>
<span class="nc" id="L1765">            int currentSpanPosition = Spans.NO_MORE_POSITIONS;</span>
            // check and initialize for each span
<span class="nc bnc" id="L1767" title="All 2 branches missed.">            for (int i = 0; i &lt; spansList.length; i++) {</span>
<span class="nc bnc" id="L1768" title="All 2 branches missed.">              if (spansList[i].docID() == nextDoc) {</span>
<span class="nc" id="L1769">                int tmpStartPosition = spansList[i].nextStartPosition();</span>
<span class="nc bnc" id="L1770" title="All 2 branches missed.">                if (tmpStartPosition &lt; Spans.NO_MORE_POSITIONS) {</span>
<span class="nc" id="L1771">                  finishedSpansList[i] = false;</span>
                } else {
<span class="nc" id="L1773">                  finishedSpansList[i] = true;</span>
                }
                // compute position
<span class="nc bnc" id="L1776" title="All 2 branches missed.">                currentSpanPosition = (currentSpanPosition == Spans.NO_MORE_POSITIONS)</span>
                    ? tmpStartPosition
<span class="nc" id="L1778">                    : Math.min(currentSpanPosition, tmpStartPosition);</span>
<span class="nc" id="L1779">              } else {</span>
<span class="nc" id="L1780">                finishedSpansList[i] = true;</span>
              }
            }
            // loop over matches
<span class="nc bnc" id="L1784" title="All 4 branches missed.">            while (currentMatchPosition &lt; matchList.size()</span>
                &amp;&amp; currentSpanPosition &lt; Spans.NO_MORE_POSITIONS) {

<span class="nc" id="L1787">              if (currentSpanPosition &lt; matchList</span>
<span class="nc bnc" id="L1788" title="All 2 branches missed.">                  .get(currentMatchPosition).startPosition) {</span>
                // do nothing, match not reached
<span class="nc bnc" id="L1790" title="All 2 branches missed.">              } else if (currentSpanPosition &gt; lastMatchStartPosition) {</span>
                // finish, past last match
<span class="nc" id="L1792">                break;</span>
              } else {
                // advance matches
<span class="nc bnc" id="L1795" title="All 2 branches missed.">                while (currentMatchPosition &lt; matchList.size()</span>
                    &amp;&amp; currentSpanPosition &gt; matchList
<span class="nc bnc" id="L1797" title="All 2 branches missed.">                        .get(currentMatchPosition).startPosition) {</span>
                  // store current match, not relevant
<span class="nc" id="L1799">                  newMatchList.add(matchList.get(currentMatchPosition));</span>
<span class="nc" id="L1800">                  currentMatchPosition++;</span>
                }
                // equal startPosition
<span class="nc bnc" id="L1803" title="All 2 branches missed.">                while (currentMatchPosition &lt; matchList.size()</span>
                    &amp;&amp; currentSpanPosition == matchList
<span class="nc bnc" id="L1805" title="All 2 branches missed.">                        .get(currentMatchPosition).startPosition) {</span>
                  // check for each span
<span class="nc bnc" id="L1807" title="All 2 branches missed.">                  for (int i = 0; i &lt; spansList.length; i++) {</span>
                    // equal start and end, therefore match
<span class="nc bnc" id="L1809" title="All 4 branches missed.">                    if (!finishedSpansList[i] &amp;&amp; spansList[i].docID() == nextDoc</span>
<span class="nc" id="L1810">                        &amp;&amp; spansList[i].startPosition() == matchList</span>
<span class="nc bnc" id="L1811" title="All 2 branches missed.">                            .get(currentMatchPosition).startPosition</span>
<span class="nc" id="L1812">                        &amp;&amp; spansList[i].endPosition() == matchList</span>
<span class="nc bnc" id="L1813" title="All 2 branches missed.">                            .get(currentMatchPosition).endPosition) {</span>
                      // administration
<span class="nc" id="L1815">                      total++;</span>
<span class="nc" id="L1816">                      subSum[i]++;</span>
<span class="nc bnc" id="L1817" title="All 2 branches missed.">                      if (newNextDocs[i]) {</span>
<span class="nc" id="L1818">                        subN[i]++;</span>
<span class="nc" id="L1819">                        newNextDocs[i] = false;</span>
<span class="nc" id="L1820">                        newNextDoc = false;</span>
                      }
<span class="nc bnc" id="L1822" title="All 2 branches missed.">                    } else if (!finishedSpansList[i]</span>
<span class="nc bnc" id="L1823" title="All 2 branches missed.">                        &amp;&amp; spansList[i].docID() == nextDoc</span>
<span class="nc" id="L1824">                        &amp;&amp; spansList[i].startPosition() == matchList</span>
<span class="nc bnc" id="L1825" title="All 2 branches missed.">                            .get(currentMatchPosition).startPosition) {</span>
                      // no match, store
<span class="nc" id="L1827">                      newMatchList.add(matchList.get(currentMatchPosition));</span>
                    }
                  }
<span class="nc" id="L1830">                  currentMatchPosition++;</span>
                }
              }

              // advance spans
<span class="nc bnc" id="L1835" title="All 2 branches missed.">              if (currentMatchPosition &lt; matchList.size()) {</span>
<span class="nc" id="L1836">                currentSpanPosition = Spans.NO_MORE_POSITIONS;</span>
<span class="nc bnc" id="L1837" title="All 2 branches missed.">                for (int i = 0; i &lt; spansList.length; i++) {</span>
<span class="nc bnc" id="L1838" title="All 2 branches missed.">                  if (!finishedSpansList[i]</span>
<span class="nc bnc" id="L1839" title="All 2 branches missed.">                      &amp;&amp; (spansList[i].docID() == nextDoc)) {</span>
<span class="nc bnc" id="L1840" title="All 2 branches missed.">                    while (!finishedSpansList[i]</span>
<span class="nc" id="L1841">                        &amp;&amp; spansList[i].startPosition() &lt; matchList</span>
<span class="nc bnc" id="L1842" title="All 2 branches missed.">                            .get(currentMatchPosition).startPosition) {</span>
<span class="nc" id="L1843">                      int tmpStartPosition = spansList[i].nextStartPosition();</span>
<span class="nc bnc" id="L1844" title="All 2 branches missed.">                      if (tmpStartPosition == Spans.NO_MORE_POSITIONS) {</span>
<span class="nc" id="L1845">                        finishedSpansList[i] = true;</span>
                      }
<span class="nc" id="L1847">                    }</span>
<span class="nc bnc" id="L1848" title="All 2 branches missed.">                    if (!finishedSpansList[i]) {</span>
<span class="nc bnc" id="L1849" title="All 2 branches missed.">                      currentSpanPosition = (currentSpanPosition == Spans.NO_MORE_POSITIONS)</span>
<span class="nc" id="L1850">                          ? spansList[i].startPosition()</span>
<span class="nc" id="L1851">                          : Math.min(currentSpanPosition,</span>
<span class="nc" id="L1852">                              spansList[i].startPosition());</span>
                    }
                  } else {
<span class="nc" id="L1855">                    finishedSpansList[i] = true;</span>
                  }
                }
              }
            }
<span class="nc bnc" id="L1860" title="All 2 branches missed.">            if (!newNextDoc) {</span>
              // add other matches
<span class="nc bnc" id="L1862" title="All 2 branches missed.">              while (currentMatchPosition &lt; matchList.size()) {</span>
<span class="nc" id="L1863">                newMatchList.add(matchList.get(currentMatchPosition));</span>
<span class="nc" id="L1864">                currentMatchPosition++;</span>
              }
              // update administration
<span class="nc bnc" id="L1867" title="All 2 branches missed.">              if (!newMatchList.isEmpty()) {</span>
<span class="nc" id="L1868">                matchData.put(nextDoc + docBase, newMatchList);</span>
              } else {
<span class="nc" id="L1870">                matchData.put(nextDoc + docBase, null);</span>
              }
            }
          }
        }
        // advance to next document
<span class="nc" id="L1876">        nextDocCounter++;</span>
<span class="nc" id="L1877">        newNextDoc = true;</span>
<span class="nc bnc" id="L1878" title="All 2 branches missed.">        for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc" id="L1879">          newNextDocs[i] = true;</span>
        }
        // advance spans
<span class="nc bnc" id="L1882" title="All 2 branches missed.">        if (nextDocCounter &lt; docSet.size()) {</span>
<span class="nc" id="L1883">          nextDoc = Spans.NO_MORE_DOCS;</span>
          // advance spans
<span class="nc bnc" id="L1885" title="All 2 branches missed.">          for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc bnc" id="L1886" title="All 2 branches missed.">            if (spansNextDoc[i] &lt; (docSet.get(nextDocCounter) - docBase)) {</span>
<span class="nc" id="L1887">              spansNextDoc[i] = spansList[i]</span>
<span class="nc" id="L1888">                  .advance(docSet.get(nextDocCounter) - docBase);</span>
            }
<span class="nc bnc" id="L1890" title="All 2 branches missed.">            if (spansNextDoc[i] &lt; Spans.NO_MORE_DOCS) {</span>
<span class="nc bnc" id="L1891" title="All 2 branches missed.">              nextDoc = (nextDoc == Spans.NO_MORE_DOCS) ? spansNextDoc[i]</span>
<span class="nc" id="L1892">                  : Math.min(nextDoc, spansNextDoc[i]);</span>
            }
          }
        }
      }
      // update administration
<span class="nc bnc" id="L1898" title="All 2 branches missed.">      for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc bnc" id="L1899" title="All 4 branches missed.">        if (subSum[i] &gt; 0 &amp;&amp; (occurencesSum.containsKey(hitList[i]))) {</span>
<span class="nc" id="L1900">          occurencesSum.put(hitList[i],</span>
<span class="nc" id="L1901">              occurencesSum.get(hitList[i]) + subSum[i]);</span>
<span class="nc" id="L1902">          occurencesN.put(hitList[i], occurencesN.get(hitList[i]) + subN[i]);</span>
        }
      }

    }
<span class="nc" id="L1907">    return total;</span>
  }

  /**
   * Sort match list.
   *
   * @param list the list
   */
  private static void sortMatchList(List&lt;Match&gt; list) {
<span class="pc bpc" id="L1916" title="1 of 2 branches missed.">    if (list != null) {</span>
      // light sorting on start position
<span class="fc" id="L1918">      Collections.sort(list, (Match m1,</span>
<span class="fc" id="L1919">          Match m2) -&gt; (Integer.compare(m1.startPosition, m2.startPosition)));</span>
    }
<span class="fc" id="L1921">  }</span>

  /**
   * Creates the document.
   *
   * @param documentList the document list
   * @param docList the doc list
   * @param uniqueKeyField the unique key field
   * @param searcher the searcher
   * @param t the t
   * @param lrc the lrc
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createDocument(List&lt;ComponentDocument&gt; documentList,
      List&lt;Integer&gt; docList, String uniqueKeyField, IndexSearcher searcher,
      Terms t, LeafReaderContext lrc) throws IOException {
<span class="nc bnc" id="L1937" title="All 2 branches missed.">    if (documentList != null) {</span>
<span class="nc" id="L1938">      SortedSet&lt;String&gt; listStatsItems = CodecUtil.createStatsItems(&quot;sum&quot;);</span>
<span class="nc" id="L1939">      String listStatsType = CodecUtil.createStatsType(listStatsItems,</span>
          CodecUtil.STATS_TYPE_SUM, null);
<span class="nc bnc" id="L1941" title="All 2 branches missed.">      for (ComponentDocument document : documentList) {</span>
        // initialize
<span class="nc bnc" id="L1943" title="All 2 branches missed.">        for (int docId : docList) {</span>
          // get unique id
<span class="nc" id="L1945">          Document doc = searcher.doc(docId,</span>
<span class="nc" id="L1946">              new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L1947">          IndexableField indxfld = doc.getField(uniqueKeyField);</span>
          // get other doc info
<span class="nc bnc" id="L1949" title="All 2 branches missed.">          if (indxfld != null) {</span>
<span class="nc" id="L1950">            document.uniqueKey.put(docId, indxfld.stringValue());</span>
<span class="nc" id="L1951">            MtasDataCollector&lt;?, ?&gt; stats = DataCollector.getCollector(</span>
                DataCollector.COLLECTOR_TYPE_DATA, document.dataType,
                document.statsType, document.statsItems, null, null, null, null,
                null, null);
<span class="nc" id="L1955">            document.statsData.put(docId, stats);</span>
<span class="nc bnc" id="L1956" title="All 2 branches missed.">            if (document.statsList != null) {</span>
              MtasDataCollector&lt;?, ?&gt; list;
<span class="nc bnc" id="L1958" title="All 2 branches missed.">              if (document.listExpand) {</span>
<span class="nc" id="L1959">                SortedSet&lt;String&gt;[] baseStatsItems = new SortedSet[] {</span>
                    listStatsItems };
<span class="nc" id="L1961">                list = DataCollector.getCollector(</span>
                    DataCollector.COLLECTOR_TYPE_LIST, CodecUtil.DATA_TYPE_LONG,
                    listStatsType, listStatsItems, CodecUtil.STATS_TYPE_SUM,
<span class="nc" id="L1964">                    CodecUtil.SORT_DESC, 0, document.listNumber,</span>
                    new String[] { DataCollector.COLLECTOR_TYPE_LIST },
                    new String[] { CodecUtil.DATA_TYPE_LONG },
                    new String[] { listStatsType },
<span class="nc" id="L1968">                    Arrays.copyOfRange(baseStatsItems, 0,</span>
                        baseStatsItems.length),
                    new String[] { CodecUtil.STATS_TYPE_SUM },
<span class="nc" id="L1971">                    new String[] { CodecUtil.SORT_DESC }, new Integer[] { 0 },</span>
<span class="nc" id="L1972">                    new Integer[] { document.listExpandNumber }, null, null);</span>
<span class="nc" id="L1973">              } else {</span>
<span class="nc" id="L1974">                list = DataCollector.getCollector(</span>
                    DataCollector.COLLECTOR_TYPE_LIST, CodecUtil.DATA_TYPE_LONG,
                    listStatsType, listStatsItems, CodecUtil.STATS_TYPE_SUM,
<span class="nc" id="L1977">                    CodecUtil.SORT_DESC, 0, document.listNumber, null, null);</span>
              }
<span class="nc" id="L1979">              document.statsList.put(docId, list);</span>
            }
          }
<span class="nc" id="L1982">        }</span>
<span class="nc" id="L1983">      }</span>
      // collect
<span class="nc bnc" id="L1985" title="All 2 branches missed.">      if (t != null) {</span>
        BytesRef term;
        TermsEnum termsEnum;
<span class="nc" id="L1988">        PostingsEnum postingsEnum = null;</span>
        // loop over termvectors
<span class="nc bnc" id="L1990" title="All 2 branches missed.">        for (ComponentDocument document : documentList) {</span>

          List&lt;CompiledAutomaton&gt; listAutomata;
          Map&lt;String, Automaton&gt; automatonMap;
          Map&lt;String, ByteRunAutomaton&gt; byteRunAutomatonMap;
<span class="nc bnc" id="L1995" title="All 2 branches missed.">          if (document.list == null) {</span>
<span class="nc" id="L1996">            automatonMap = null;</span>
<span class="nc" id="L1997">            byteRunAutomatonMap = null;</span>
<span class="nc" id="L1998">            listAutomata = new ArrayList&lt;&gt;();</span>
            CompiledAutomaton compiledAutomaton;
            Automaton automaton;
<span class="nc bnc" id="L2001" title="All 4 branches missed.">            if ((document.regexp == null) || (document.regexp.isEmpty())) {</span>
<span class="nc" id="L2002">              RegExp re = new RegExp(</span>
                  document.prefix + MtasToken.DELIMITER + &quot;.*&quot;);
<span class="nc" id="L2004">              automaton = re.toAutomaton();</span>
<span class="nc" id="L2005">            } else {</span>
<span class="nc" id="L2006">              RegExp re = new RegExp(document.prefix + MtasToken.DELIMITER</span>
                  + document.regexp + &quot;\u0000*&quot;);
<span class="nc" id="L2008">              automaton = re.toAutomaton();</span>
            }
<span class="nc" id="L2010">            compiledAutomaton = new CompiledAutomaton(automaton);</span>
<span class="nc" id="L2011">            listAutomata.add(compiledAutomaton);</span>
<span class="nc" id="L2012">          } else {</span>
<span class="nc bnc" id="L2013" title="All 2 branches missed.">            automatonMap = MtasToken.createAutomatonMap(document.prefix,</span>
                new ArrayList&lt;String&gt;(document.list),
<span class="nc" id="L2015">                document.listRegexp ? false : true);</span>
<span class="nc" id="L2016">            byteRunAutomatonMap = MtasToken.byteRunAutomatonMap(automatonMap);</span>
<span class="nc" id="L2017">            listAutomata = MtasToken.createAutomata(document.prefix,</span>
                document.regexp, automatonMap);
          }
<span class="nc" id="L2020">          List&lt;ByteRunAutomaton&gt; ignoreByteRunAutomatonList = null;</span>
<span class="nc bnc" id="L2021" title="All 2 branches missed.">          if ((document.ignoreRegexp != null)</span>
<span class="nc bnc" id="L2022" title="All 2 branches missed.">              &amp;&amp; (!document.ignoreRegexp.isEmpty())) {</span>
<span class="nc" id="L2023">            ignoreByteRunAutomatonList = new ArrayList&lt;&gt;();</span>
<span class="nc" id="L2024">            RegExp re = new RegExp(document.prefix + MtasToken.DELIMITER</span>
                + document.ignoreRegexp + &quot;\u0000*&quot;);
<span class="nc" id="L2026">            ignoreByteRunAutomatonList</span>
<span class="nc" id="L2027">                .add(new ByteRunAutomaton(re.toAutomaton()));</span>
          }
<span class="nc bnc" id="L2029" title="All 2 branches missed.">          if (document.ignoreList != null) {</span>
<span class="nc bnc" id="L2030" title="All 2 branches missed.">            if (ignoreByteRunAutomatonList == null) {</span>
<span class="nc" id="L2031">              ignoreByteRunAutomatonList = new ArrayList&lt;&gt;();</span>
            }
<span class="nc bnc" id="L2033" title="All 2 branches missed.">            Map&lt;String, Automaton&gt; list = MtasToken.createAutomatonMap(</span>
                document.prefix, new ArrayList&lt;String&gt;(document.ignoreList),
<span class="nc" id="L2035">                document.ignoreListRegexp ? false : true);</span>
<span class="nc bnc" id="L2036" title="All 2 branches missed.">            for (Automaton automaton : list.values()) {</span>
<span class="nc" id="L2037">              ignoreByteRunAutomatonList.add(new ByteRunAutomaton(automaton));</span>
<span class="nc" id="L2038">            }</span>
          }

<span class="nc bnc" id="L2041" title="All 2 branches missed.">          for (CompiledAutomaton compiledAutomaton : listAutomata) {</span>
<span class="nc" id="L2042">            if (!compiledAutomaton.type</span>
<span class="nc bnc" id="L2043" title="All 2 branches missed.">                .equals(CompiledAutomaton.AUTOMATON_TYPE.NONE)) {</span>
<span class="nc" id="L2044">              termsEnum = t.intersect(compiledAutomaton, null);</span>
              // init
<span class="nc" id="L2046">              int initBaseSize = Math.min((int) t.size(), 1000);</span>
<span class="nc bnc" id="L2047" title="All 2 branches missed.">              int initListSize = document.statsList != null</span>
<span class="nc" id="L2048">                  ? Math.min(document.statsList.size(), initBaseSize)</span>
                  : initBaseSize;
<span class="nc" id="L2050">              HashSet&lt;MtasDataCollector&lt;?, ?&gt;&gt; initialised = new HashSet&lt;&gt;();</span>
<span class="nc bnc" id="L2051" title="All 2 branches missed.">              for (int docId : docList) {</span>
<span class="nc" id="L2052">                document.statsData.get(docId).initNewList(1);</span>
<span class="nc" id="L2053">                initialised.add(document.statsData.get(docId));</span>
<span class="nc bnc" id="L2054" title="All 2 branches missed.">                if (document.statsList != null</span>
<span class="nc bnc" id="L2055" title="All 2 branches missed.">                    &amp;&amp; document.statsList.size() &gt; 0) {</span>
<span class="nc" id="L2056">                  document.statsList.get(docId).initNewList(initListSize);</span>
<span class="nc" id="L2057">                  initialised.add(document.statsList.get(docId));</span>
                }
<span class="nc" id="L2059">              }</span>
              // fill
              int termDocId;
              boolean acceptedTerm;
<span class="nc bnc" id="L2063" title="All 2 branches missed.">              while ((term = termsEnum.next()) != null) {</span>
<span class="nc" id="L2064">                Iterator&lt;Integer&gt; docIterator = docList.iterator();</span>
<span class="nc" id="L2065">                postingsEnum = termsEnum.postings(postingsEnum,</span>
                    PostingsEnum.FREQS);
<span class="nc" id="L2067">                termDocId = -1;</span>
<span class="nc" id="L2068">                acceptedTerm = true;</span>
<span class="nc bnc" id="L2069" title="All 2 branches missed.">                if (ignoreByteRunAutomatonList != null) {</span>
<span class="nc bnc" id="L2070" title="All 2 branches missed.">                  for (ByteRunAutomaton ignoreByteRunAutomaton : ignoreByteRunAutomatonList) {</span>
<span class="nc bnc" id="L2071" title="All 2 branches missed.">                    if (ignoreByteRunAutomaton.run(term.bytes, term.offset,</span>
                        term.length)) {
<span class="nc" id="L2073">                      acceptedTerm = false;</span>
<span class="nc" id="L2074">                      break;</span>
                    }
<span class="nc" id="L2076">                  }</span>
                }
<span class="nc bnc" id="L2078" title="All 2 branches missed.">                if (acceptedTerm) {</span>
<span class="nc bnc" id="L2079" title="All 2 branches missed.">                  while (docIterator.hasNext()) {</span>
<span class="nc" id="L2080">                    int segmentDocId = docIterator.next() - lrc.docBase;</span>
<span class="nc bnc" id="L2081" title="All 4 branches missed.">                    if (segmentDocId &gt;= termDocId</span>
                        &amp;&amp; ((segmentDocId == termDocId)
                            || ((termDocId = postingsEnum
<span class="nc bnc" id="L2084" title="All 2 branches missed.">                                .advance(segmentDocId)) == segmentDocId))) {</span>
                      // register stats
<span class="nc" id="L2086">                      document.statsData.get(segmentDocId + lrc.docBase)</span>
<span class="nc" id="L2087">                          .add(new long[] { postingsEnum.freq() }, 1);</span>
                      // register list
<span class="nc bnc" id="L2089" title="All 2 branches missed.">                      if (document.statsList != null) {</span>
<span class="nc bnc" id="L2090" title="All 2 branches missed.">                        if (automatonMap != null) {</span>
                          MtasDataCollector&lt;?, ?&gt; dataCollector;
                          MtasDataCollector&lt;?, ?&gt; subSataCollector;
<span class="nc bnc" id="L2093" title="All 2 branches missed.">                          for (Entry&lt;String, ByteRunAutomaton&gt; entry : byteRunAutomatonMap</span>
<span class="nc" id="L2094">                              .entrySet()) {</span>
<span class="nc" id="L2095">                            ByteRunAutomaton bra = entry.getValue();</span>
<span class="nc bnc" id="L2096" title="All 2 branches missed.">                            if (bra.run(term.bytes, term.offset, term.length)) {</span>
<span class="nc" id="L2097">                              dataCollector = document.statsList</span>
<span class="nc" id="L2098">                                  .get(segmentDocId + lrc.docBase);</span>
<span class="nc" id="L2099">                              subSataCollector = dataCollector.add(</span>
<span class="nc" id="L2100">                                  entry.getKey(),</span>
<span class="nc" id="L2101">                                  new long[] { postingsEnum.freq() }, 1);</span>
<span class="nc bnc" id="L2102" title="All 4 branches missed.">                              if (document.listExpand</span>
                                  &amp;&amp; subSataCollector != null) {
<span class="nc bnc" id="L2104" title="All 2 branches missed.">                                if (!initialised.contains(subSataCollector)) {</span>
<span class="nc" id="L2105">                                  subSataCollector.initNewList(initBaseSize);</span>
<span class="nc" id="L2106">                                  initialised.add(subSataCollector);</span>
                                }
<span class="nc" id="L2108">                                subSataCollector.add(</span>
<span class="nc" id="L2109">                                    MtasToken.getPostfixFromValue(term),</span>
<span class="nc" id="L2110">                                    new long[] { postingsEnum.freq() }, 1);</span>
                              }
                            }
<span class="nc" id="L2113">                          }</span>
                        } else {
<span class="nc" id="L2115">                          document.statsList.get(segmentDocId + lrc.docBase)</span>
<span class="nc" id="L2116">                              .add(MtasToken.getPostfixFromValue(term),</span>
<span class="nc" id="L2117">                                  new long[] { postingsEnum.freq() }, 1);</span>
                        }
                      }
                    }
<span class="nc" id="L2121">                  }</span>
                }
<span class="nc" id="L2123">              }</span>
              // close
<span class="nc bnc" id="L2125" title="All 2 branches missed.">              for (MtasDataCollector&lt;?, ?&gt; item : initialised) {</span>
<span class="nc" id="L2126">                item.closeNewList();</span>
<span class="nc" id="L2127">              }</span>
<span class="nc" id="L2128">              initialised.clear();</span>
            }
<span class="nc" id="L2130">          }</span>
<span class="nc" id="L2131">        }</span>
      }
    }
<span class="nc" id="L2134">  }</span>

  /**
   * Creates the kwic.
   *
   * @param kwicList the kwic list
   * @param spansMatchData the spans match data
   * @param docList the doc list
   * @param field the field
   * @param docBase the doc base
   * @param uniqueKeyField the unique key field
   * @param mtasCodecInfo the mtas codec info
   * @param searcher the searcher
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createKwic(List&lt;ComponentKwic&gt; kwicList,
      Map&lt;MtasSpanQuery, Map&lt;Integer, List&lt;Match&gt;&gt;&gt; spansMatchData,
      List&lt;Integer&gt; docList, String field, int docBase, String uniqueKeyField,
      CodecInfo mtasCodecInfo, IndexSearcher searcher) throws IOException {
<span class="nc bnc" id="L2153" title="All 2 branches missed.">    if (kwicList != null) {</span>
<span class="nc bnc" id="L2154" title="All 2 branches missed.">      for (ComponentKwic kwic : kwicList) {</span>
<span class="nc" id="L2155">        Map&lt;Integer, List&lt;Match&gt;&gt; matchData = spansMatchData.get(kwic.query);</span>
        List&lt;Match&gt; matchList;
<span class="nc bnc" id="L2157" title="All 2 branches missed.">        if (kwic.output.equals(ComponentKwic.KWIC_OUTPUT_HIT)) {</span>
<span class="nc bnc" id="L2158" title="All 2 branches missed.">          for (int docId : docList) {</span>
<span class="nc bnc" id="L2159" title="All 2 branches missed.">            if (matchData != null</span>
<span class="nc bnc" id="L2160" title="All 2 branches missed.">                &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
              // get unique id
<span class="nc" id="L2162">              Document doc = searcher.doc(docId,</span>
<span class="nc" id="L2163">                  new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L2164">              IndexableField indxfld = doc.getField(uniqueKeyField);</span>
              // get other doc info
<span class="nc bnc" id="L2166" title="All 2 branches missed.">              if (indxfld != null) {</span>
<span class="nc" id="L2167">                kwic.uniqueKey.put(docId, indxfld.stringValue());</span>
              }
<span class="nc" id="L2169">              kwic.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L2170">              IndexDoc mDoc = mtasCodecInfo.getDoc(field, (docId - docBase));</span>
<span class="nc bnc" id="L2171" title="All 2 branches missed.">              if (mDoc != null) {</span>
<span class="nc" id="L2172">                kwic.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L2173">                kwic.maxPosition.put(docId, mDoc.maxPosition);</span>
              }
              // kwiclist
<span class="nc" id="L2176">              List&lt;KwicHit&gt; kwicItemList = new ArrayList&lt;&gt;();</span>
<span class="nc" id="L2177">              int number = 0;</span>
<span class="nc bnc" id="L2178" title="All 2 branches missed.">              for (Match m : matchList) {</span>
<span class="nc bnc" id="L2179" title="All 2 branches missed.">                if (kwic.number != null</span>
<span class="nc bnc" id="L2180" title="All 2 branches missed.">                    &amp;&amp; number &gt;= (kwic.start + kwic.number)) {</span>
<span class="nc" id="L2181">                  break;</span>
                }
<span class="nc bnc" id="L2183" title="All 2 branches missed.">                if (number &gt;= kwic.start) {</span>
<span class="nc" id="L2184">                  int startPosition = m.startPosition;</span>
<span class="nc" id="L2185">                  int endPosition = m.endPosition - 1;</span>
<span class="nc" id="L2186">                  List&lt;MtasTreeHit&lt;String&gt;&gt; terms = mtasCodecInfo</span>
<span class="nc" id="L2187">                      .getPositionedTermsByPrefixesAndPositionRange(field,</span>
                          (docId - docBase), kwic.prefixes,
<span class="nc" id="L2189">                          Math.max(mDoc.minPosition, startPosition - kwic.left),</span>
<span class="nc" id="L2190">                          Math.min(mDoc.maxPosition, endPosition + kwic.right));</span>
                  // construct hit
<span class="nc" id="L2192">                  Map&lt;Integer, List&lt;String&gt;&gt; kwicListHits = new HashMap&lt;&gt;();</span>
<span class="nc" id="L2193">                  for (int position = Math.max(mDoc.minPosition,</span>
<span class="nc bnc" id="L2194" title="All 2 branches missed.">                      startPosition - kwic.left); position &lt;= Math.min(</span>
                          mDoc.maxPosition,
<span class="nc" id="L2196">                          endPosition + kwic.right); position++) {</span>
<span class="nc" id="L2197">                    kwicListHits.put(position, new ArrayList&lt;String&gt;());</span>
                  }
                  List&lt;String&gt; termList;
<span class="nc bnc" id="L2200" title="All 2 branches missed.">                  for (MtasTreeHit&lt;String&gt; term : terms) {</span>
<span class="nc" id="L2201">                    for (int position = Math.max((startPosition - kwic.left),</span>
<span class="nc bnc" id="L2202" title="All 2 branches missed.">                        term.startPosition); position &lt;= Math.min(</span>
                            (endPosition + kwic.right),
<span class="nc" id="L2204">                            term.endPosition); position++) {</span>
<span class="nc" id="L2205">                      termList = kwicListHits.get(position);</span>
<span class="nc" id="L2206">                      termList.add(term.data);</span>
                    }
<span class="nc" id="L2208">                  }</span>
<span class="nc" id="L2209">                  kwicItemList.add(new KwicHit(m, kwicListHits));</span>
                }
<span class="nc" id="L2211">                number++;</span>
<span class="nc" id="L2212">              }</span>
<span class="nc" id="L2213">              kwic.hits.put(docId, kwicItemList);</span>
            }
<span class="nc" id="L2215">          }</span>
<span class="nc bnc" id="L2216" title="All 2 branches missed.">        } else if (kwic.output.equals(ComponentKwic.KWIC_OUTPUT_TOKEN)) {</span>
<span class="nc bnc" id="L2217" title="All 2 branches missed.">          for (int docId : docList) {</span>
<span class="nc bnc" id="L2218" title="All 2 branches missed.">            if (matchData != null</span>
<span class="nc bnc" id="L2219" title="All 2 branches missed.">                &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
              // get unique id
<span class="nc" id="L2221">              Document doc = searcher.doc(docId,</span>
<span class="nc" id="L2222">                  new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
              // get other doc info
<span class="nc" id="L2224">              IndexableField indxfld = doc.getField(uniqueKeyField);</span>
<span class="nc bnc" id="L2225" title="All 2 branches missed.">              if (indxfld != null) {</span>
<span class="nc" id="L2226">                kwic.uniqueKey.put(docId, indxfld.stringValue());</span>
              }
<span class="nc" id="L2228">              kwic.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L2229">              IndexDoc mDoc = mtasCodecInfo.getDoc(field, (docId - docBase));</span>
<span class="nc bnc" id="L2230" title="All 2 branches missed.">              if (mDoc != null) {</span>
<span class="nc" id="L2231">                kwic.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L2232">                kwic.maxPosition.put(docId, mDoc.maxPosition);</span>
<span class="nc" id="L2233">                List&lt;KwicToken&gt; kwicItemList = new ArrayList&lt;&gt;();</span>
<span class="nc" id="L2234">                int number = 0;</span>
<span class="nc bnc" id="L2235" title="All 2 branches missed.">                for (Match m : matchList) {</span>
<span class="nc bnc" id="L2236" title="All 2 branches missed.">                  if (kwic.number != null</span>
<span class="nc bnc" id="L2237" title="All 2 branches missed.">                      &amp;&amp; number &gt;= (kwic.start + kwic.number)) {</span>
<span class="nc" id="L2238">                    break;</span>
                  }
<span class="nc bnc" id="L2240" title="All 2 branches missed.">                  if (number &gt;= kwic.start) {</span>
<span class="nc" id="L2241">                    int startPosition = m.startPosition;</span>
<span class="nc" id="L2242">                    int endPosition = m.endPosition - 1;</span>
                    List&lt;MtasTokenString&gt; tokens;
<span class="nc" id="L2244">                    tokens = mtasCodecInfo.getPrefixFilteredObjectsByPositions(</span>
                        field, (docId - docBase), kwic.prefixes,
<span class="nc" id="L2246">                        Math.max(mDoc.minPosition, startPosition - kwic.left),</span>
<span class="nc" id="L2247">                        Math.min(mDoc.maxPosition, endPosition + kwic.right));</span>
<span class="nc" id="L2248">                    kwicItemList.add(new KwicToken(m, tokens));</span>
                  }
<span class="nc" id="L2250">                  number++;</span>
<span class="nc" id="L2251">                }</span>
<span class="nc" id="L2252">                kwic.tokens.put(docId, kwicItemList);</span>
              }
            }
<span class="nc" id="L2255">          }</span>
        }
<span class="nc" id="L2257">      }</span>
    }
<span class="nc" id="L2259">  }</span>

  /**
   * Creates the facet base.
   *
   * @param cf the cf
   * @param level the level
   * @param dataCollector the data collector
   * @param positionsData the positions data
   * @param spansNumberData the spans number data
   * @param facetData the facet data
   * @param docSet the doc set
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createFacetBase(ComponentFacet cf, int level,
      MtasDataCollector&lt;?, ?&gt; dataCollector,
      Map&lt;Integer, Integer&gt; positionsData,
      Map&lt;MtasSpanQuery, Map&lt;Integer, Integer&gt;&gt; spansNumberData,
      Map&lt;String, SortedMap&lt;String, int[]&gt;&gt; facetData, Integer[] docSet)
      throws IOException {
<span class="nc bnc" id="L2279" title="All 2 branches missed.">    for (MtasFunctionParserFunction function : cf.baseFunctionParserFunctions[level]) {</span>
<span class="nc bnc" id="L2280" title="All 2 branches missed.">      if (function.needArgumentsNumber() &gt; cf.spanQueries.length) {</span>
<span class="nc" id="L2281">        throw new IOException(&quot;function &quot; + function + &quot; expects (at least) &quot;</span>
<span class="nc" id="L2282">            + function.needArgumentsNumber() + &quot; queries&quot;);</span>
      }
    }
<span class="nc" id="L2285">    Map&lt;String, int[]&gt; list = facetData.get(cf.baseFields[level]);</span>
<span class="nc bnc" id="L2286" title="All 2 branches missed.">    if (dataCollector != null) {</span>
<span class="nc" id="L2287">      MtasDataCollector&lt;?, ?&gt; subDataCollector = null;</span>
<span class="nc" id="L2288">      dataCollector.initNewList(1);</span>
<span class="nc bnc" id="L2289" title="All 2 branches missed.">      if (cf.baseFunctionList[level] != null) {</span>
        SubComponentFunction[] tmpList;
<span class="nc bnc" id="L2291" title="All 2 branches missed.">        if (!cf.baseFunctionList[level].containsKey(dataCollector)) {</span>
<span class="nc" id="L2292">          tmpList = new SubComponentFunction[cf.baseFunctionParserFunctions[level].length];</span>
<span class="nc" id="L2293">          cf.baseFunctionList[level].put(dataCollector, tmpList);</span>
<span class="nc bnc" id="L2294" title="All 2 branches missed.">          for (int i = 0; i &lt; cf.baseFunctionParserFunctions[level].length; i++) {</span>
            try {
<span class="nc" id="L2296">              tmpList[i] = new SubComponentFunction(</span>
                  DataCollector.COLLECTOR_TYPE_LIST,
                  cf.baseFunctionKeys[level][i], cf.baseFunctionTypes[level][i],
<span class="nc" id="L2299">                  cf.baseFunctionParserFunctions[level][i], null, null, 0,</span>
<span class="nc" id="L2300">                  Integer.MAX_VALUE, null, null);</span>

<span class="nc" id="L2302">            } catch (ParseException e) {</span>
<span class="nc" id="L2303">              throw new IOException(e.getMessage());</span>
<span class="nc" id="L2304">            }</span>
          }
        } else {
<span class="nc" id="L2307">          tmpList = cf.baseFunctionList[level].get(dataCollector);</span>
        }
<span class="nc bnc" id="L2309" title="All 2 branches missed.">        for (SubComponentFunction function : tmpList) {</span>
<span class="nc" id="L2310">          function.dataCollector.initNewList(1);</span>
        }
      }
      // check type
<span class="nc" id="L2314">      if (dataCollector.getCollectorType()</span>
<span class="nc bnc" id="L2315" title="All 2 branches missed.">          .equals(DataCollector.COLLECTOR_TYPE_LIST)) {</span>
<span class="nc" id="L2316">        dataCollector.setWithTotal();</span>
        // only if documents and facets
<span class="nc bnc" id="L2318" title="All 4 branches missed.">        if (docSet.length &gt; 0 &amp;&amp; list.size() &gt; 0) {</span>
<span class="nc" id="L2319">          HashMap&lt;String, Integer[]&gt; docLists = new HashMap&lt;&gt;();</span>
<span class="nc" id="L2320">          HashMap&lt;String, String&gt; groupedKeys = new HashMap&lt;&gt;();</span>
<span class="nc" id="L2321">          boolean documentsInFacets = false;</span>
          // compute intersections
<span class="nc bnc" id="L2323" title="All 2 branches missed.">          for (Entry&lt;String, int[]&gt; entry : list.entrySet()) {</span>
            // fill grouped keys
<span class="nc bnc" id="L2325" title="All 2 branches missed.">            if (!groupedKeys.containsKey(entry.getKey())) {</span>
<span class="nc" id="L2326">              groupedKeys.put(entry.getKey(), groupedKeyName(entry.getKey(),</span>
                  cf.baseRangeSizes[level], cf.baseRangeBases[level]));
            }
            // intersect docSet with docList
<span class="nc" id="L2330">            Integer[] docList = intersectedDocList(entry.getValue(), docSet);</span>
<span class="nc bnc" id="L2331" title="All 4 branches missed.">            if (docList != null &amp;&amp; docList.length &gt; 0) {</span>
<span class="nc" id="L2332">              documentsInFacets = true;</span>
            }
            // update docLists
<span class="nc bnc" id="L2335" title="All 2 branches missed.">            if (docLists.containsKey(groupedKeys.get(entry.getKey()))) {</span>
<span class="nc" id="L2336">              docLists.put(groupedKeys.get(entry.getKey()), mergeDocLists(</span>
<span class="nc" id="L2337">                  docLists.get(groupedKeys.get(entry.getKey())), docList));</span>
            } else {
<span class="nc" id="L2339">              docLists.put(groupedKeys.get(entry.getKey()), docList);</span>
            }
<span class="nc" id="L2341">          }</span>
          // compute stats for each key
<span class="nc bnc" id="L2343" title="All 2 branches missed.">          if (documentsInFacets) {</span>
<span class="nc" id="L2344">            Map&lt;Integer, long[]&gt; args = computeArguments(spansNumberData,</span>
                cf.spanQueries, docSet);
<span class="nc bnc" id="L2346" title="All 2 branches missed.">            if (cf.baseDataTypes[level].equals(CodecUtil.DATA_TYPE_LONG)) {</span>
              // check functions
<span class="nc" id="L2348">              boolean applySumRule = false;</span>
<span class="nc bnc" id="L2349" title="All 2 branches missed.">              if (cf.baseStatsTypes[level].equals(CodecUtil.STATS_BASIC)</span>
<span class="nc bnc" id="L2350" title="All 6 branches missed.">                  &amp;&amp; cf.baseParsers[level].sumRule()</span>
                  &amp;&amp; (cf.baseMinimumLongs[level] == null)
                  &amp;&amp; (cf.baseMaximumLongs[level] == null)) {
<span class="nc" id="L2353">                applySumRule = true;</span>
<span class="nc bnc" id="L2354" title="All 2 branches missed.">                if (cf.baseFunctionList[level].get(dataCollector) != null) {</span>
                  for (SubComponentFunction function : cf.baseFunctionList[level]
<span class="nc bnc" id="L2356" title="All 2 branches missed.">                      .get(dataCollector)) {</span>
<span class="nc bnc" id="L2357" title="All 2 branches missed.">                    if (!function.statsType.equals(CodecUtil.STATS_BASIC)</span>
<span class="nc bnc" id="L2358" title="All 2 branches missed.">                        || !function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L2359" title="All 2 branches missed.">                        || function.parserFunction.needPositions()) {</span>
<span class="nc" id="L2360">                      applySumRule = false;</span>
<span class="nc" id="L2361">                      break;</span>
                    }
                  }
                }
              }
<span class="nc bnc" id="L2366" title="All 2 branches missed.">              if (applySumRule) {</span>
<span class="nc bnc" id="L2367" title="All 2 branches missed.">                for (String key : new LinkedHashSet&lt;String&gt;(</span>
<span class="nc" id="L2368">                    groupedKeys.values())) {</span>
<span class="nc bnc" id="L2369" title="All 2 branches missed.">                  if (docLists.get(key).length &gt; 0) {</span>
                    // initialise
<span class="nc" id="L2371">                    Integer[] subDocSet = docLists.get(key);</span>
<span class="nc" id="L2372">                    int length = cf.baseParsers[level].needArgumentsNumber();</span>
<span class="nc" id="L2373">                    long[] valueSum = new long[length];</span>
<span class="nc" id="L2374">                    long valuePositions = 0;</span>
                    // collect
<span class="nc bnc" id="L2376" title="All 2 branches missed.">                    if (subDocSet.length &gt; 0) {</span>
                      long[] tmpArgs;
<span class="nc bnc" id="L2378" title="All 2 branches missed.">                      for (int docId : subDocSet) {</span>
<span class="nc" id="L2379">                        tmpArgs = args.get(docId);</span>
<span class="nc bnc" id="L2380" title="All 2 branches missed.">                        if (positionsData != null</span>
<span class="nc bnc" id="L2381" title="All 2 branches missed.">                            &amp;&amp; positionsData.containsKey(docId)</span>
<span class="nc bnc" id="L2382" title="All 2 branches missed.">                            &amp;&amp; positionsData.get(docId) != null) {</span>
<span class="nc" id="L2383">                          valuePositions += positionsData.get(docId)</span>
<span class="nc" id="L2384">                              .longValue();</span>
                        }
<span class="nc bnc" id="L2386" title="All 2 branches missed.">                        if (tmpArgs != null) {</span>
<span class="nc bnc" id="L2387" title="All 2 branches missed.">                          for (int i = 0; i &lt; length; i++) {</span>
<span class="nc" id="L2388">                            valueSum[i] += tmpArgs[i];</span>
                          }
                        }
                      }
                      long value;
                      try {
<span class="nc" id="L2394">                        value = cf.baseParsers[level].getValueLong(valueSum,</span>
                            valuePositions);
<span class="nc" id="L2396">                        subDataCollector = dataCollector.add(key, value,</span>
                            subDocSet.length);
<span class="nc" id="L2398">                      } catch (IOException e) {</span>
<span class="nc" id="L2399">                        log.debug(e);</span>
<span class="nc" id="L2400">                        dataCollector.error(key, e.getMessage());</span>
<span class="nc" id="L2401">                        subDataCollector = null;</span>
<span class="nc" id="L2402">                      }</span>
<span class="nc bnc" id="L2403" title="All 2 branches missed.">                      if (cf.baseFunctionList[level] != null</span>
                          &amp;&amp; cf.baseFunctionList[level]
<span class="nc bnc" id="L2405" title="All 2 branches missed.">                              .containsKey(dataCollector)) {</span>
<span class="nc" id="L2406">                        SubComponentFunction[] functionList = cf.baseFunctionList[level]</span>
<span class="nc" id="L2407">                            .get(dataCollector);</span>
<span class="nc bnc" id="L2408" title="All 2 branches missed.">                        for (SubComponentFunction function : functionList) {</span>
<span class="nc" id="L2409">                          if (function.dataType</span>
<span class="nc bnc" id="L2410" title="All 2 branches missed.">                              .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                            try {
<span class="nc" id="L2412">                              long valueLong = function.parserFunction</span>
<span class="nc" id="L2413">                                  .getValueLong(valueSum, valuePositions);</span>
<span class="nc" id="L2414">                              function.dataCollector.add(key, valueLong,</span>
                                  subDocSet.length);
<span class="nc" id="L2416">                            } catch (IOException e) {</span>
<span class="nc" id="L2417">                              log.debug(e);</span>
<span class="nc" id="L2418">                              function.dataCollector.error(key, e.getMessage());</span>
<span class="nc" id="L2419">                            }</span>
<span class="nc" id="L2420">                          } else if (function.dataType</span>
<span class="nc bnc" id="L2421" title="All 2 branches missed.">                              .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
                            try {
<span class="nc" id="L2423">                              double valueDouble = function.parserFunction</span>
<span class="nc" id="L2424">                                  .getValueDouble(valueSum, valuePositions);</span>
<span class="nc" id="L2425">                              function.dataCollector.add(key, valueDouble,</span>
                                  subDocSet.length);
<span class="nc" id="L2427">                            } catch (IOException e) {</span>
<span class="nc" id="L2428">                              log.debug(e);</span>
<span class="nc" id="L2429">                              function.dataCollector.error(key, e.getMessage());</span>
<span class="nc" id="L2430">                            }</span>
                          }
                        }
                      }
<span class="nc bnc" id="L2434" title="All 2 branches missed.">                      if (subDataCollector != null) {</span>
<span class="nc" id="L2435">                        createFacetBase(cf, (level + 1), subDataCollector,</span>
                            positionsData, spansNumberData, facetData,
                            subDocSet);
                      }
                    }
                  }
<span class="nc" id="L2441">                }</span>
              } else {
<span class="nc bnc" id="L2443" title="All 2 branches missed.">                for (String key : new LinkedHashSet&lt;String&gt;(</span>
<span class="nc" id="L2444">                    groupedKeys.values())) {</span>
<span class="nc bnc" id="L2445" title="All 2 branches missed.">                  if (docLists.get(key).length &gt; 0) {</span>
                    // initialise
<span class="nc" id="L2447">                    Integer[] subDocSet = docLists.get(key);</span>
                    // collect
<span class="nc bnc" id="L2449" title="All 2 branches missed.">                    if (subDocSet.length &gt; 0 &amp;&amp; cf.baseDataTypes[level]</span>
<span class="nc bnc" id="L2450" title="All 2 branches missed.">                        .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                      // check for functions
<span class="nc" id="L2452">                      long[][] functionValuesLong = null;</span>
<span class="nc" id="L2453">                      double[][] functionValuesDouble = null;</span>
<span class="nc" id="L2454">                      int[] functionNumber = null;</span>
<span class="nc" id="L2455">                      SubComponentFunction[] functionList = null;</span>
<span class="nc bnc" id="L2456" title="All 2 branches missed.">                      if (cf.baseFunctionList[level] != null</span>
                          &amp;&amp; cf.baseFunctionList[level]
<span class="nc bnc" id="L2458" title="All 2 branches missed.">                              .containsKey(dataCollector)) {</span>
<span class="nc" id="L2459">                        functionList = cf.baseFunctionList[level]</span>
<span class="nc" id="L2460">                            .get(dataCollector);</span>
<span class="nc" id="L2461">                        functionValuesLong = new long[functionList.length][];</span>
<span class="nc" id="L2462">                        functionValuesDouble = new double[functionList.length][];</span>
<span class="nc" id="L2463">                        functionNumber = new int[functionList.length];</span>
<span class="nc bnc" id="L2464" title="All 2 branches missed.">                        for (int i = 0; i &lt; functionList.length; i++) {</span>
<span class="nc" id="L2465">                          functionValuesLong[i] = new long[subDocSet.length];</span>
<span class="nc" id="L2466">                          functionValuesDouble[i] = new double[subDocSet.length];</span>
                        }
                      }
                      // check main
<span class="nc" id="L2470">                      int number = 0;</span>
<span class="nc" id="L2471">                      Integer[] restrictedSubDocSet = new Integer[subDocSet.length];</span>
<span class="nc" id="L2472">                      long[] values = new long[subDocSet.length];</span>
<span class="nc bnc" id="L2473" title="All 2 branches missed.">                      for (int docId : subDocSet) {</span>
<span class="nc" id="L2474">                        long[] tmpArgs = args.get(docId);</span>
<span class="nc bnc" id="L2475" title="All 2 branches missed.">                        int tmpPositions = (positionsData == null) ? 0</span>
<span class="nc" id="L2476">                            : positionsData.get(docId);</span>
<span class="nc" id="L2477">                        long value = cf.baseParsers[level].getValueLong(tmpArgs,</span>
                            tmpPositions);
<span class="nc bnc" id="L2479" title="All 2 branches missed.">                        if ((cf.baseMinimumLongs[level] == null</span>
<span class="nc bnc" id="L2480" title="All 4 branches missed.">                            || value &gt;= cf.baseMinimumLongs[level])</span>
                            &amp;&amp; (cf.baseMaximumLongs[level] == null
<span class="nc bnc" id="L2482" title="All 2 branches missed.">                                || value &lt;= cf.baseMaximumLongs[level])) {</span>
<span class="nc" id="L2483">                          values[number] = value;</span>
<span class="nc" id="L2484">                          restrictedSubDocSet[number] = docId;</span>
<span class="nc" id="L2485">                          number++;</span>
<span class="nc bnc" id="L2486" title="All 2 branches missed.">                          if (functionList != null) {</span>
<span class="nc bnc" id="L2487" title="All 2 branches missed.">                            for (int i = 0; i &lt; functionList.length; i++) {</span>
<span class="nc" id="L2488">                              SubComponentFunction function = functionList[i];</span>
<span class="nc" id="L2489">                              if (function.dataType</span>
<span class="nc bnc" id="L2490" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                                try {
<span class="nc" id="L2492">                                  functionValuesLong[i][functionNumber[i]] = function.parserFunction</span>
<span class="nc" id="L2493">                                      .getValueLong(tmpArgs, tmpPositions);</span>
<span class="nc" id="L2494">                                  functionNumber[i]++;</span>
<span class="nc" id="L2495">                                } catch (IOException e) {</span>
<span class="nc" id="L2496">                                  log.debug(e);</span>
<span class="nc" id="L2497">                                  function.dataCollector.error(key,</span>
<span class="nc" id="L2498">                                      e.getMessage());</span>
<span class="nc" id="L2499">                                }</span>
<span class="nc" id="L2500">                              } else if (function.dataType</span>
<span class="nc bnc" id="L2501" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
                                try {
<span class="nc" id="L2503">                                  functionValuesDouble[i][functionNumber[i]] = function.parserFunction</span>
<span class="nc" id="L2504">                                      .getValueDouble(tmpArgs, tmpPositions);</span>
<span class="nc" id="L2505">                                  functionNumber[i]++;</span>
<span class="nc" id="L2506">                                } catch (IOException e) {</span>
<span class="nc" id="L2507">                                  log.debug(e);</span>
<span class="nc" id="L2508">                                  function.dataCollector.error(key,</span>
<span class="nc" id="L2509">                                      e.getMessage());</span>
<span class="nc" id="L2510">                                }</span>
                              }
                            }
                          }
                        }
                      }
<span class="nc bnc" id="L2516" title="All 2 branches missed.">                      if (number &gt; 0) {</span>
<span class="nc" id="L2517">                        subDataCollector = dataCollector.add(key, values,</span>
                            number);
<span class="nc bnc" id="L2519" title="All 2 branches missed.">                        if (cf.baseFunctionList[level] != null</span>
                            &amp;&amp; cf.baseFunctionList[level]
<span class="nc bnc" id="L2521" title="All 2 branches missed.">                                .containsKey(dataCollector)) {</span>
<span class="nc bnc" id="L2522" title="All 2 branches missed.">                          for (int i = 0; i &lt; functionList.length; i++) {</span>
<span class="nc" id="L2523">                            SubComponentFunction function = functionList[i];</span>
<span class="nc" id="L2524">                            if (function.dataType</span>
<span class="nc bnc" id="L2525" title="All 2 branches missed.">                                .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L2526">                              function.dataCollector.add(key,</span>
                                  functionValuesLong[i], functionNumber[i]);
<span class="nc" id="L2528">                            } else if (function.dataType</span>
<span class="nc bnc" id="L2529" title="All 2 branches missed.">                                .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L2530">                              function.dataCollector.add(key,</span>
                                  functionValuesDouble[i], functionNumber[i]);
                            }
                          }
                        }
<span class="nc bnc" id="L2535" title="All 2 branches missed.">                        if (subDataCollector != null) {</span>
<span class="nc" id="L2536">                          createFacetBase(cf, (level + 1), subDataCollector,</span>
                              positionsData, spansNumberData, facetData, Arrays
<span class="nc" id="L2538">                                  .copyOfRange(restrictedSubDocSet, 0, number));</span>
                        }
                      }
                    }
                  }
<span class="nc" id="L2543">                }</span>
              }
<span class="nc" id="L2545">            } else {</span>
<span class="nc" id="L2546">              throw new IOException(</span>
                  &quot;unexpected dataType &quot; + cf.baseDataTypes[level]);
            }
          }
<span class="nc" id="L2550">        }</span>
      } else {
<span class="nc" id="L2552">        throw new IOException(</span>
<span class="nc" id="L2553">            &quot;unexpected type &quot; + dataCollector.getCollectorType());</span>
      }
<span class="nc" id="L2555">      dataCollector.closeNewList();</span>
<span class="nc bnc" id="L2556" title="All 2 branches missed.">      if (cf.baseFunctionList[level] != null</span>
<span class="nc bnc" id="L2557" title="All 2 branches missed.">          &amp;&amp; cf.baseFunctionList[level].containsKey(dataCollector)) {</span>
<span class="nc" id="L2558">        SubComponentFunction[] tmpList = cf.baseFunctionList[level]</span>
<span class="nc" id="L2559">            .get(dataCollector);</span>
<span class="nc bnc" id="L2560" title="All 2 branches missed.">        for (SubComponentFunction function : tmpList) {</span>
<span class="nc" id="L2561">          function.dataCollector.closeNewList();</span>
        }
      }
    }

<span class="nc" id="L2566">  }</span>

  /**
   * Grouped key name.
   *
   * @param key the key
   * @param baseRangeSize the base range size
   * @param baseRangeBase the base range base
   * @return the string
   */
  private static String groupedKeyName(String key, Double baseRangeSize,
      Double baseRangeBase) {
<span class="nc" id="L2578">    final double precision = 0.000001;</span>
<span class="nc bnc" id="L2579" title="All 4 branches missed.">    if (baseRangeSize == null || baseRangeSize &lt;= 0) {</span>
<span class="nc" id="L2580">      return key;</span>
    } else {
      Double doubleKey;
      Double doubleBase;
      Double doubleNumber;
      Double doubleStart;
      Double doubleEnd;
      try {
<span class="nc" id="L2588">        doubleKey = Double.parseDouble(key);</span>
<span class="nc bnc" id="L2589" title="All 2 branches missed.">        doubleBase = baseRangeBase != null ? baseRangeBase : 0;</span>
<span class="nc" id="L2590">        doubleNumber = Math.floor((doubleKey - doubleBase) / baseRangeSize);</span>
<span class="nc" id="L2591">        doubleStart = doubleBase + doubleNumber * baseRangeSize;</span>
<span class="nc" id="L2592">        doubleEnd = doubleStart + baseRangeSize;</span>
<span class="nc" id="L2593">      } catch (NumberFormatException e) {</span>
<span class="nc" id="L2594">        return key;</span>
<span class="nc" id="L2595">      }</span>
      // integer
<span class="nc bnc" id="L2597" title="All 2 branches missed.">      if (Math.abs(baseRangeSize - Math.floor(baseRangeSize)) &lt; precision</span>
<span class="nc bnc" id="L2598" title="All 2 branches missed.">          &amp;&amp; Math.abs(doubleBase - Math.floor(doubleBase)) &lt; precision) {</span>
        try {
<span class="nc bnc" id="L2600" title="All 2 branches missed.">          if (baseRangeSize &gt; 1) {</span>
<span class="nc" id="L2601">            return String.format(&quot;%.0f&quot;, doubleStart) + &quot;-&quot;</span>
<span class="nc" id="L2602">                + String.format(&quot;%.0f&quot;, doubleEnd - 1);</span>
          } else {
<span class="nc" id="L2604">            return String.format(&quot;%.0f&quot;, doubleStart);</span>
          }
<span class="nc" id="L2606">        } catch (NumberFormatException e) {</span>
<span class="nc" id="L2607">          return key;</span>
        }
      } else {
<span class="nc" id="L2610">        return &quot;[&quot; + doubleStart + &quot;,&quot; + doubleEnd + &quot;)&quot;;</span>
      }
    }
  }

  /**
   * Merge doc lists.
   *
   * @param a the a
   * @param b the b
   * @return the integer[]
   */
  private static Integer[] mergeDocLists(Integer[] a, Integer[] b) {
<span class="nc" id="L2623">    Integer[] answer = new Integer[a.length + b.length];</span>
<span class="nc" id="L2624">    int i = 0;</span>
<span class="nc" id="L2625">    int j = 0;</span>
<span class="nc" id="L2626">    int k = 0;</span>
    Integer tmp;
<span class="nc bnc" id="L2628" title="All 4 branches missed.">    while (i &lt; a.length &amp;&amp; j &lt; b.length) {</span>
<span class="nc bnc" id="L2629" title="All 2 branches missed.">      tmp = a[i] &lt; b[j] ? a[i++] : b[j++];</span>
<span class="nc bnc" id="L2630" title="All 4 branches missed.">      for (; i &lt; a.length &amp;&amp; a[i].equals(tmp); i++)</span>
        ;
<span class="nc bnc" id="L2632" title="All 4 branches missed.">      for (; j &lt; b.length &amp;&amp; b[j].equals(tmp); j++)</span>
        ;
<span class="nc" id="L2634">      answer[k++] = tmp;</span>
    }
<span class="nc bnc" id="L2636" title="All 2 branches missed.">    while (i &lt; a.length) {</span>
<span class="nc" id="L2637">      tmp = a[i++];</span>
<span class="nc bnc" id="L2638" title="All 4 branches missed.">      for (; i &lt; a.length &amp;&amp; a[i].equals(tmp); i++)</span>
        ;
<span class="nc" id="L2640">      answer[k++] = tmp;</span>
    }
<span class="nc bnc" id="L2642" title="All 2 branches missed.">    while (j &lt; b.length) {</span>
<span class="nc" id="L2643">      tmp = b[j++];</span>
<span class="nc bnc" id="L2644" title="All 4 branches missed.">      for (; j &lt; b.length &amp;&amp; b[j].equals(tmp); j++)</span>
        ;
<span class="nc" id="L2646">      answer[k++] = tmp;</span>
    }
<span class="nc" id="L2648">    return Arrays.copyOf(answer, k);</span>
  }

  /**
   * Creates the facet.
   *
   * @param facetList the facet list
   * @param positionsData the positions data
   * @param spansNumberData the spans number data
   * @param facetData the facet data
   * @param docSet the doc set
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createFacet(List&lt;ComponentFacet&gt; facetList,
      Map&lt;Integer, Integer&gt; positionsData,
      Map&lt;MtasSpanQuery, Map&lt;Integer, Integer&gt;&gt; spansNumberData,
      Map&lt;String, SortedMap&lt;String, int[]&gt;&gt; facetData, List&lt;Integer&gt; docSet)
      throws IOException {

<span class="nc bnc" id="L2667" title="All 2 branches missed.">    if (facetList != null) {</span>
<span class="nc bnc" id="L2668" title="All 2 branches missed.">      for (ComponentFacet cf : facetList) {</span>
<span class="nc bnc" id="L2669" title="All 2 branches missed.">        if (cf.baseFields.length &gt; 0) {</span>
<span class="nc" id="L2670">          createFacetBase(cf, 0, cf.dataCollector, positionsData,</span>
              spansNumberData, facetData,
<span class="nc" id="L2672">              docSet.toArray(new Integer[docSet.size()]));</span>
        }
<span class="nc" id="L2674">      }</span>
    }
<span class="nc" id="L2676">  }</span>

  /**
   * Creates the termvector full.
   *
   * @param termVectorList the term vector list
   * @param positionsData the positions data
   * @param docSet the doc set
   * @param t the t
   * @param r the r
   * @param lrc the lrc
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createTermvectorFull(
      List&lt;ComponentTermVector&gt; termVectorList,
      Map&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet, Terms t,
      LeafReader r, LeafReaderContext lrc) throws IOException {
<span class="pc bpc" id="L2693" title="1 of 2 branches missed.">    if (t != null) {</span>
      BytesRef term;
      TermsEnum termsEnum;
<span class="fc" id="L2696">      PostingsEnum postingsEnum = null;</span>
<span class="fc" id="L2697">      String segmentName = &quot;segment&quot; + lrc.ord;</span>
<span class="fc" id="L2698">      int segmentNumber = lrc.parent.leaves().size();</span>
      // loop over termvectors
<span class="fc bfc" id="L2700" title="All 2 branches covered.">      for (ComponentTermVector termVector : termVectorList) {</span>
<span class="fc bfc" id="L2701" title="All 4 branches covered.">        if (termVector.full || termVector.list != null) {</span>
<span class="fc bfc" id="L2702" title="All 2 branches covered.">          if (termVector.full) {</span>
<span class="fc" id="L2703">            termVector.subComponentFunction.dataCollector.setWithTotal();</span>
          }
          List&lt;CompiledAutomaton&gt; listAutomata;
          Map&lt;String, Automaton&gt; automatonMap;
<span class="fc bfc" id="L2707" title="All 2 branches covered.">          if (termVector.list == null) {</span>
<span class="fc" id="L2708">            listAutomata = new ArrayList&lt;&gt;();</span>
            CompiledAutomaton compiledAutomaton;
            Automaton automaton;
<span class="pc bpc" id="L2711" title="1 of 4 branches missed.">            if ((termVector.regexp == null) || (termVector.regexp.isEmpty())) {</span>
<span class="fc" id="L2712">              RegExp re = new RegExp(</span>
                  termVector.prefix + MtasToken.DELIMITER + &quot;.*&quot;);
<span class="fc" id="L2714">              automaton = re.toAutomaton();</span>
<span class="fc" id="L2715">            } else {</span>
<span class="fc" id="L2716">              RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
                  + termVector.regexp + &quot;\u0000*&quot;);
<span class="fc" id="L2718">              automaton = re.toAutomaton();</span>
            }
<span class="fc" id="L2720">            compiledAutomaton = new CompiledAutomaton(automaton);</span>
<span class="fc" id="L2721">            listAutomata.add(compiledAutomaton);</span>
<span class="fc" id="L2722">          } else {</span>
<span class="fc bfc" id="L2723" title="All 2 branches covered.">            automatonMap = MtasToken.createAutomatonMap(termVector.prefix,</span>
                new ArrayList&lt;String&gt;(termVector.list),
<span class="fc" id="L2725">                termVector.listRegexp ? false : true);</span>
<span class="fc" id="L2726">            listAutomata = MtasToken.createAutomata(termVector.prefix,</span>
                termVector.regexp, automatonMap);
          }
<span class="fc" id="L2729">          List&lt;ByteRunAutomaton&gt; ignoreByteRunAutomatonList = null;</span>
<span class="fc bfc" id="L2730" title="All 2 branches covered.">          if ((termVector.ignoreRegexp != null)</span>
<span class="pc bpc" id="L2731" title="1 of 2 branches missed.">              &amp;&amp; (!termVector.ignoreRegexp.isEmpty())) {</span>
<span class="fc" id="L2732">            ignoreByteRunAutomatonList = new ArrayList&lt;&gt;();</span>
<span class="fc" id="L2733">            RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
                + termVector.ignoreRegexp + &quot;\u0000*&quot;);
<span class="fc" id="L2735">            ignoreByteRunAutomatonList</span>
<span class="fc" id="L2736">                .add(new ByteRunAutomaton(re.toAutomaton()));</span>
          }
<span class="fc bfc" id="L2738" title="All 2 branches covered.">          if (termVector.ignoreList != null) {</span>
<span class="pc bpc" id="L2739" title="1 of 2 branches missed.">            if (ignoreByteRunAutomatonList == null) {</span>
<span class="nc" id="L2740">              ignoreByteRunAutomatonList = new ArrayList&lt;&gt;();</span>
            }
<span class="pc bpc" id="L2742" title="1 of 2 branches missed.">            Map&lt;String, Automaton&gt; list = MtasToken.createAutomatonMap(</span>
                termVector.prefix, new ArrayList&lt;String&gt;(termVector.ignoreList),
<span class="fc" id="L2744">                termVector.ignoreListRegexp ? false : true);</span>
<span class="fc bfc" id="L2745" title="All 2 branches covered.">            for (Automaton automaton : list.values()) {</span>
<span class="fc" id="L2746">              ignoreByteRunAutomatonList.add(new ByteRunAutomaton(automaton));</span>
<span class="fc" id="L2747">            }</span>
          }

<span class="fc bfc" id="L2750" title="All 2 branches covered.">          for (CompiledAutomaton compiledAutomaton : listAutomata) {</span>
<span class="fc" id="L2751">            if (!compiledAutomaton.type</span>
<span class="fc bfc" id="L2752" title="All 2 branches covered.">                .equals(CompiledAutomaton.AUTOMATON_TYPE.NORMAL)) {</span>
<span class="fc" id="L2753">              if (compiledAutomaton.type</span>
<span class="pc bpc" id="L2754" title="1 of 2 branches missed.">                  .equals(CompiledAutomaton.AUTOMATON_TYPE.NONE)) {</span>
                // do nothing
              } else {
<span class="nc" id="L2757">                throw new IOException(</span>
                    &quot;compiledAutomaton is &quot; + compiledAutomaton.type);
              }
            } else {
<span class="fc" id="L2761">              termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="fc" id="L2762">              int initSize = Math.min((int) t.size(), 1000);</span>
<span class="fc" id="L2763">              termVector.subComponentFunction.dataCollector.initNewList(</span>
                  initSize, segmentName, segmentNumber, termVector.boundary);
<span class="fc" id="L2765">              boolean doBasic = termVector.subComponentFunction.dataCollector</span>
<span class="fc" id="L2766">                  .getStatsType().equals(CodecUtil.STATS_BASIC);</span>
<span class="pc bpc" id="L2767" title="1 of 2 branches missed.">              if (termVector.functions != null) {</span>
<span class="pc bpc" id="L2768" title="1 of 2 branches missed.">                for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2769">                  function.dataCollector.initNewList(initSize);</span>
<span class="nc bnc" id="L2770" title="All 4 branches missed.">                  doBasic = doBasic ? (function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L2771" title="All 2 branches missed.">                      &amp;&amp; !function.parserFunction.needPositions()</span>
<span class="nc" id="L2772">                      &amp;&amp; function.dataCollector.getStatsType()</span>
<span class="nc bnc" id="L2773" title="All 2 branches missed.">                          .equals(CodecUtil.STATS_BASIC))</span>
                      : doBasic;
<span class="nc" id="L2775">                }</span>
              }
              // only if documents
<span class="pc bpc" id="L2778" title="1 of 2 branches missed.">              if (!docSet.isEmpty()) {</span>
                int termDocId;
                boolean acceptedTerm;
                String key;
                // loop over terms
<span class="fc bfc" id="L2783" title="All 2 branches covered.">                while ((term = termsEnum.next()) != null) {</span>
<span class="pc bpc" id="L2784" title="1 of 2 branches missed.">                  if (validateTermWithStartValue(term, termVector)) {</span>
<span class="fc" id="L2785">                    termDocId = -1;</span>
<span class="fc" id="L2786">                    acceptedTerm = true;</span>
<span class="fc bfc" id="L2787" title="All 2 branches covered.">                    if (ignoreByteRunAutomatonList != null) {</span>
<span class="fc bfc" id="L2788" title="All 2 branches covered.">                      for (ByteRunAutomaton ignoreByteRunAutomaton : ignoreByteRunAutomatonList) {</span>
<span class="fc bfc" id="L2789" title="All 2 branches covered.">                        if (ignoreByteRunAutomaton.run(term.bytes, term.offset,</span>
                            term.length)) {
<span class="fc" id="L2791">                          acceptedTerm = false;</span>
<span class="fc" id="L2792">                          break;</span>
                        }
<span class="fc" id="L2794">                      }</span>
                    }
<span class="fc bfc" id="L2796" title="All 2 branches covered.">                    if (acceptedTerm) {</span>
<span class="fc bfc" id="L2797" title="All 2 branches covered.">                      if (doBasic) {</span>
                        // compute numbers;
<span class="fc" id="L2799">                        TermvectorNumberBasic numberBasic = computeTermvectorNumberBasic(</span>
                            docSet, termDocId, termsEnum, r, lrc, postingsEnum);
                        // register
<span class="fc bfc" id="L2802" title="All 2 branches covered.">                        if (numberBasic.docNumber &gt; 0) {</span>
<span class="fc" id="L2803">                          long valueLong = 0;</span>
<span class="fc" id="L2804">                          key = MtasToken.getPostfixFromValue(term);</span>
                          try {
<span class="fc" id="L2806">                            valueLong = termVector.subComponentFunction.parserFunction</span>
<span class="fc" id="L2807">                                .getValueLong(numberBasic.valueSum, 1);</span>
<span class="nc" id="L2808">                          } catch (IOException e) {</span>
<span class="nc" id="L2809">                            log.debug(e);</span>
<span class="nc" id="L2810">                            termVector.subComponentFunction.dataCollector.error(</span>
<span class="nc" id="L2811">                                MtasToken.getPostfixFromValue(term),</span>
<span class="nc" id="L2812">                                e.getMessage());</span>
<span class="fc" id="L2813">                          }</span>
<span class="fc" id="L2814">                          termVector.subComponentFunction.dataCollector.add(key,</span>
                              valueLong, numberBasic.docNumber);
<span class="pc bpc" id="L2816" title="1 of 2 branches missed.">                          if (termVector.functions != null) {</span>
<span class="pc bpc" id="L2817" title="1 of 2 branches missed.">                            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2818">                              if (function.dataType</span>
<span class="nc bnc" id="L2819" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L2820">                                long valueFunction = function.parserFunction</span>
<span class="nc" id="L2821">                                    .getValueLong(numberBasic.valueSum, 0);</span>
<span class="nc" id="L2822">                                function.dataCollector.add(key, valueFunction,</span>
                                    numberBasic.docNumber);
<span class="nc" id="L2824">                              } else if (function.dataType</span>
<span class="nc bnc" id="L2825" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L2826">                                double valueFunction = function.parserFunction</span>
<span class="nc" id="L2827">                                    .getValueDouble(numberBasic.valueSum, 0);</span>
<span class="nc" id="L2828">                                function.dataCollector.add(key, valueFunction,</span>
                                    numberBasic.docNumber);
                              }
<span class="nc" id="L2831">                            }</span>
                          }
                        }
<span class="fc" id="L2834">                      } else {</span>
<span class="fc" id="L2835">                        TermvectorNumberFull numberFull = computeTermvectorNumberFull(</span>
                            docSet, termDocId, termsEnum, lrc, postingsEnum,
                            positionsData);
<span class="pc bpc" id="L2838" title="1 of 2 branches missed.">                        if (numberFull.docNumber &gt; 0) {</span>
<span class="fc" id="L2839">                          long[] valuesLong = new long[numberFull.docNumber];</span>
<span class="fc" id="L2840">                          key = MtasToken.getPostfixFromValue(term);</span>
<span class="fc bfc" id="L2841" title="All 2 branches covered.">                          for (int i = 0; i &lt; numberFull.docNumber; i++) {</span>
                            try {
<span class="fc" id="L2843">                              valuesLong[i] = termVector.subComponentFunction.parserFunction</span>
<span class="fc" id="L2844">                                  .getValueLong(</span>
                                      new long[] { numberFull.args[i] },
                                      numberFull.positions[i]);
<span class="nc" id="L2847">                            } catch (IOException e) {</span>
<span class="nc" id="L2848">                              log.debug(e);</span>
<span class="nc" id="L2849">                              termVector.subComponentFunction.dataCollector</span>
<span class="nc" id="L2850">                                  .error(key, e.getMessage());</span>
<span class="fc" id="L2851">                            }</span>
                          }
<span class="fc" id="L2853">                          termVector.subComponentFunction.dataCollector.add(key,</span>
                              valuesLong, valuesLong.length);
<span class="pc bpc" id="L2855" title="1 of 2 branches missed.">                          if (termVector.functions != null) {</span>
<span class="pc bpc" id="L2856" title="1 of 2 branches missed.">                            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2857">                              if (function.dataType</span>
<span class="nc bnc" id="L2858" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L2859">                                valuesLong = new long[numberFull.docNumber];</span>
<span class="nc bnc" id="L2860" title="All 2 branches missed.">                                for (int i = 0; i &lt; numberFull.docNumber; i++) {</span>
                                  try {
<span class="nc" id="L2862">                                    valuesLong[i] = function.parserFunction</span>
<span class="nc" id="L2863">                                        .getValueLong(</span>
                                            new long[] { numberFull.args[i] },
                                            numberFull.positions[i]);
<span class="nc" id="L2866">                                  } catch (IOException e) {</span>
<span class="nc" id="L2867">                                    log.debug(e);</span>
<span class="nc" id="L2868">                                    function.dataCollector.error(key,</span>
<span class="nc" id="L2869">                                        e.getMessage());</span>
<span class="nc" id="L2870">                                  }</span>
                                }
<span class="nc" id="L2872">                                function.dataCollector.add(key, valuesLong,</span>
                                    valuesLong.length);
<span class="nc" id="L2874">                              } else if (function.dataType</span>
<span class="nc bnc" id="L2875" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L2876">                                double[] valuesDouble = new double[numberFull.docNumber];</span>
<span class="nc bnc" id="L2877" title="All 2 branches missed.">                                for (int i = 0; i &lt; numberFull.docNumber; i++) {</span>
                                  try {
<span class="nc" id="L2879">                                    valuesDouble[i] = function.parserFunction</span>
<span class="nc" id="L2880">                                        .getValueDouble(</span>
                                            new long[] { numberFull.args[i] },
                                            numberFull.positions[i]);
<span class="nc" id="L2883">                                  } catch (IOException e) {</span>
<span class="nc" id="L2884">                                    log.debug(e);</span>
<span class="nc" id="L2885">                                    function.dataCollector.error(key,</span>
<span class="nc" id="L2886">                                        e.getMessage());</span>
<span class="nc" id="L2887">                                  }</span>
                                }
<span class="nc" id="L2889">                                function.dataCollector.add(key, valuesDouble,</span>
                                    valuesDouble.length);
                              }
<span class="nc" id="L2892">                            }</span>
                          }
                        }

<span class="fc" id="L2896">                      }</span>
                    }
                  }
                }
              }
<span class="fc" id="L2901">              termVector.subComponentFunction.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L2902" title="1 of 2 branches missed.">              if (termVector.functions != null) {</span>
<span class="pc bpc" id="L2903" title="1 of 2 branches missed.">                for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2904">                  function.dataCollector.closeNewList();</span>
<span class="nc" id="L2905">                }</span>
              }
            }
<span class="fc" id="L2908">          }</span>
        }
<span class="fc" id="L2910">      }</span>
    }
<span class="fc" id="L2912">  }</span>

  /**
   * Creates the termvector first round.
   *
   * @param termVectorList the term vector list
   * @param positionsData the positions data
   * @param docSet the doc set
   * @param t the t
   * @param r the r
   * @param lrc the lrc
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createTermvectorFirstRound(
      List&lt;ComponentTermVector&gt; termVectorList,
      Map&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet, Terms t,
      LeafReader r, LeafReaderContext lrc) throws IOException {
<span class="pc bpc" id="L2929" title="1 of 2 branches missed.">    if (t != null) {</span>
      BytesRef term;
      TermsEnum termsEnum;
<span class="fc" id="L2932">      PostingsEnum postingsEnum = null;</span>
<span class="fc" id="L2933">      String segmentName = &quot;segment&quot; + lrc.ord;</span>
<span class="fc" id="L2934">      String[] mutableKey = new String[1];</span>
<span class="fc" id="L2935">      int segmentNumber = lrc.parent.leaves().size();</span>
      // loop over termvectors
<span class="fc bfc" id="L2937" title="All 2 branches covered.">      for (ComponentTermVector termVector : termVectorList) {</span>
        CompiledAutomaton compiledAutomaton;
<span class="pc bpc" id="L2939" title="1 of 4 branches missed.">        if ((termVector.regexp == null) || (termVector.regexp.isEmpty())) {</span>
<span class="fc" id="L2940">          RegExp re = new RegExp(</span>
              termVector.prefix + MtasToken.DELIMITER + &quot;.*&quot;);
<span class="fc" id="L2942">          compiledAutomaton = new CompiledAutomaton(re.toAutomaton());</span>
<span class="fc" id="L2943">        } else {</span>
<span class="fc" id="L2944">          RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
              + termVector.regexp + &quot;\u0000*&quot;);
<span class="fc" id="L2946">          compiledAutomaton = new CompiledAutomaton(re.toAutomaton());</span>
        }
<span class="fc" id="L2948">        List&lt;ByteRunAutomaton&gt; ignoreByteRunAutomatonList = null;</span>
<span class="fc bfc" id="L2949" title="All 2 branches covered.">        if ((termVector.ignoreRegexp != null)</span>
<span class="pc bpc" id="L2950" title="1 of 2 branches missed.">            &amp;&amp; (!termVector.ignoreRegexp.isEmpty())) {</span>
<span class="fc" id="L2951">          ignoreByteRunAutomatonList = new ArrayList&lt;&gt;();</span>
<span class="fc" id="L2952">          RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
              + termVector.ignoreRegexp + &quot;\u0000*&quot;);
<span class="fc" id="L2954">          ignoreByteRunAutomatonList</span>
<span class="fc" id="L2955">              .add(new ByteRunAutomaton(re.toAutomaton()));</span>
        }
<span class="fc bfc" id="L2957" title="All 2 branches covered.">        if (termVector.ignoreList != null) {</span>
<span class="pc bpc" id="L2958" title="1 of 2 branches missed.">          if (ignoreByteRunAutomatonList == null) {</span>
<span class="nc" id="L2959">            ignoreByteRunAutomatonList = new ArrayList&lt;&gt;();</span>
          }
<span class="pc bpc" id="L2961" title="1 of 2 branches missed.">          Map&lt;String, Automaton&gt; list = MtasToken.createAutomatonMap(</span>
              termVector.prefix, new ArrayList&lt;String&gt;(termVector.ignoreList),
<span class="fc" id="L2963">              termVector.ignoreListRegexp ? false : true);</span>
<span class="fc bfc" id="L2964" title="All 2 branches covered.">          for (Automaton automaton : list.values()) {</span>
<span class="fc" id="L2965">            ignoreByteRunAutomatonList.add(new ByteRunAutomaton(automaton));</span>
<span class="fc" id="L2966">          }</span>
        }
<span class="fc bfc" id="L2968" title="All 4 branches covered.">        if (!termVector.full &amp;&amp; termVector.list == null) {</span>
<span class="fc" id="L2969">          termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="fc" id="L2970">          int initSize = Math.min((int) t.size(), 1000);</span>
<span class="fc" id="L2971">          termVector.subComponentFunction.dataCollector.initNewList(initSize,</span>
              segmentName, segmentNumber, termVector.boundary);
<span class="pc bpc" id="L2973" title="1 of 2 branches missed.">          if (termVector.functions != null) {</span>
<span class="pc bpc" id="L2974" title="1 of 2 branches missed.">            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2975">              function.dataCollector.initNewList(initSize);</span>
<span class="nc" id="L2976">            }</span>
          }
          // only if documents
<span class="pc bpc" id="L2979" title="1 of 2 branches missed.">          if (!docSet.isEmpty()) {</span>
            int termDocId;
<span class="fc" id="L2981">            int termNumberMaximum = termVector.number;</span>
<span class="fc" id="L2982">            HashMap&lt;BytesRef, RegisterStatus&gt; computeFullList = new HashMap&lt;&gt;();</span>
            RegisterStatus registerStatus;
            // basic, don't need full values
<span class="fc" id="L2985">            if (termVector.subComponentFunction.sortType</span>
<span class="fc bfc" id="L2986" title="All 2 branches covered.">                .equals(CodecUtil.SORT_TERM)</span>
                || termVector.subComponentFunction.sortType
<span class="pc bpc" id="L2988" title="1 of 2 branches missed.">                    .equals(CodecUtil.STATS_TYPE_SUM)</span>
                || termVector.subComponentFunction.sortType
<span class="nc bnc" id="L2990" title="All 2 branches missed.">                    .equals(CodecUtil.STATS_TYPE_N)) {</span>
<span class="fc" id="L2991">              int termCounter = 0;</span>

              boolean continueAfterPreliminaryCheck;
<span class="fc" id="L2994">              boolean preliminaryCheck = false;</span>
<span class="pc bpc" id="L2995" title="1 of 4 branches missed.">              if (r.getLiveDocs() == null &amp;&amp; (docSet.size() != r.numDocs())) {</span>
<span class="nc" id="L2996">                preliminaryCheck = true;</span>
              }
              // loop over terms
              boolean acceptedTerm;
<span class="fc bfc" id="L3000" title="All 2 branches covered.">              while ((term = termsEnum.next()) != null) {</span>
<span class="pc bpc" id="L3001" title="1 of 2 branches missed.">                if (validateTermWithStartValue(term, termVector)) {</span>
<span class="fc" id="L3002">                  termDocId = -1;</span>
<span class="fc" id="L3003">                  acceptedTerm = true;</span>
<span class="fc bfc" id="L3004" title="All 2 branches covered.">                  if (ignoreByteRunAutomatonList != null) {</span>
<span class="fc bfc" id="L3005" title="All 2 branches covered.">                    for (ByteRunAutomaton ignoreByteRunAutomaton : ignoreByteRunAutomatonList) {</span>
<span class="pc bpc" id="L3006" title="1 of 2 branches missed.">                      if (ignoreByteRunAutomaton.run(term.bytes, term.offset,</span>
                          term.length)) {
<span class="nc" id="L3008">                        acceptedTerm = false;</span>
<span class="nc" id="L3009">                        break;</span>
                      }
<span class="fc" id="L3011">                    }</span>
                  }
<span class="pc bpc" id="L3013" title="1 of 2 branches missed.">                  if (acceptedTerm) {</span>
<span class="fc" id="L3014">                    continueAfterPreliminaryCheck = true;</span>
<span class="fc" id="L3015">                    mutableKey[0] = null;</span>
<span class="pc bpc" id="L3016" title="1 of 2 branches missed.">                    if (preliminaryCheck) {</span>
                      try {
<span class="nc" id="L3018">                        TermvectorNumberBasic preliminaryNumberBasic = computeTermvectorNumberBasic(</span>
                            termsEnum, r);
<span class="nc bnc" id="L3020" title="All 2 branches missed.">                        if (preliminaryNumberBasic.docNumber &gt; 0) {</span>
<span class="nc" id="L3021">                          continueAfterPreliminaryCheck = preliminaryRegisterValue(</span>
                              term, termVector, preliminaryNumberBasic,
<span class="nc" id="L3023">                              termNumberMaximum, segmentNumber, mutableKey);</span>
                        } else {
<span class="nc" id="L3025">                          continueAfterPreliminaryCheck = false;</span>
                        }
<span class="nc" id="L3027">                      } catch (IOException e) {</span>
<span class="nc" id="L3028">                        log.debug(e);</span>
<span class="nc" id="L3029">                        continueAfterPreliminaryCheck = true;</span>
<span class="nc" id="L3030">                      }</span>
                    }
<span class="pc bpc" id="L3032" title="1 of 2 branches missed.">                    if (continueAfterPreliminaryCheck) {</span>
                      // compute numbers;
<span class="fc" id="L3034">                      TermvectorNumberBasic numberBasic = computeTermvectorNumberBasic(</span>
                          docSet, termDocId, termsEnum, r, lrc, postingsEnum);
                      // register
<span class="fc bfc" id="L3037" title="All 2 branches covered.">                      if (numberBasic.docNumber &gt; 0) {</span>
<span class="fc" id="L3038">                        termCounter++;</span>
<span class="fc" id="L3039">                        registerStatus = registerValue(term, termVector,</span>
<span class="fc" id="L3040">                            numberBasic, termNumberMaximum, segmentNumber,</span>
                            false, mutableKey);
<span class="fc bfc" id="L3042" title="All 2 branches covered.">                        if (registerStatus != null) {</span>
<span class="fc" id="L3043">                          computeFullList.put(BytesRef.deepCopyOf(term),</span>
                              registerStatus);
                        }
                      }
                    }
                    // stop after termCounterMaximum
<span class="fc" id="L3049">                    if (termVector.subComponentFunction.sortType</span>
<span class="fc bfc" id="L3050" title="All 2 branches covered.">                        .equals(CodecUtil.SORT_TERM)</span>
                        &amp;&amp; termVector.subComponentFunction.sortDirection
<span class="fc bfc" id="L3052" title="All 4 branches covered.">                            .equals(CodecUtil.SORT_ASC)</span>
                        &amp;&amp; termCounter &gt;= termNumberMaximum) {
<span class="fc" id="L3054">                      break;</span>
                    }
                  }
                }
              }
              // rerun for full
<span class="fc bfc" id="L3060" title="All 2 branches covered.">              if (computeFullList.size() &gt; 0) {</span>
<span class="fc" id="L3061">                termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="fc bfc" id="L3062" title="All 2 branches covered.">                while ((term = termsEnum.next()) != null) {</span>
<span class="pc bpc" id="L3063" title="1 of 2 branches missed.">                  if (validateTermWithStartValue(term, termVector)) {</span>
<span class="fc" id="L3064">                    termDocId = -1;</span>
<span class="fc" id="L3065">                    mutableKey[0] = null;</span>
                    // only if (probably) needed
<span class="fc bfc" id="L3067" title="All 2 branches covered.">                    if (computeFullList.containsKey(term)) {</span>
<span class="fc" id="L3068">                      registerStatus = computeFullList.get(term);</span>
                      boolean doAdd;
<span class="fc" id="L3070">                      doAdd = termVector.subComponentFunction.sortType</span>
<span class="fc" id="L3071">                          .equals(CodecUtil.SORT_TERM);</span>
<span class="fc" id="L3072">                      doAdd |= termVector.subComponentFunction.sortDirection</span>
<span class="fc" id="L3073">                          .equals(CodecUtil.SORT_ASC);</span>
<span class="pc bpc" id="L3074" title="1 of 2 branches missed.">                      doAdd |= termVector.list != null;</span>
<span class="fc" id="L3075">                      doAdd |= termVector.boundaryRegistration;</span>
<span class="fc" id="L3076">                      doAdd |= registerStatus.force;</span>
<span class="fc" id="L3077">                      doAdd |= termVector.subComponentFunction.dataCollector</span>
<span class="fc" id="L3078">                          .validateSegmentBoundary(registerStatus.sortValue);</span>
<span class="fc bfc" id="L3079" title="All 2 branches covered.">                      if (doAdd) {</span>
<span class="fc" id="L3080">                        TermvectorNumberFull numberFull = computeTermvectorNumberFull(</span>
                            docSet, termDocId, termsEnum, lrc, postingsEnum,
                            positionsData);
<span class="pc bpc" id="L3083" title="1 of 2 branches missed.">                        if (numberFull.docNumber &gt; 0) {</span>
<span class="fc" id="L3084">                          termCounter++;</span>
<span class="fc" id="L3085">                          registerValue(term, termVector, numberFull,</span>
                              mutableKey);
                        }
                      }
<span class="fc" id="L3089">                    }</span>
                  }
                }
<span class="fc" id="L3092">                computeFullList.clear();</span>
              }
<span class="fc" id="L3094">            } else {</span>
<span class="nc" id="L3095">              throw new IOException(</span>
                  &quot;sort '&quot; + termVector.subComponentFunction.sortType + &quot; &quot;
                      + termVector.subComponentFunction.sortDirection
                      + &quot;' not supported&quot;);
            }
            // finish if segments are used
<span class="fc" id="L3101">            termVector.subComponentFunction.dataCollector</span>
<span class="fc" id="L3102">                .closeSegmentKeyValueRegistration();</span>
<span class="pc bpc" id="L3103" title="1 of 2 branches missed.">            if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3104" title="1 of 2 branches missed.">              for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3105">                function.dataCollector.closeSegmentKeyValueRegistration();</span>
<span class="nc" id="L3106">              }</span>
            }
          }
<span class="fc" id="L3109">          termVector.subComponentFunction.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L3110" title="1 of 2 branches missed.">          if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3111" title="1 of 2 branches missed.">            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3112">              function.dataCollector.closeNewList();</span>
<span class="nc" id="L3113">            }</span>
          }
        }
<span class="fc" id="L3116">      }</span>
    }
<span class="fc" id="L3118">  }</span>

  /**
   * Creates the termvector second round.
   *
   * @param termVectorList the term vector list
   * @param positionsData the positions data
   * @param docSet the doc set
   * @param t the t
   * @param r the r
   * @param lrc the lrc
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static void createTermvectorSecondRound(
      List&lt;ComponentTermVector&gt; termVectorList,
      Map&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet, Terms t,
      LeafReader r, LeafReaderContext lrc) throws IOException {
<span class="pc bpc" id="L3135" title="1 of 2 branches missed.">    if (t != null) {</span>
      BytesRef term;
      TermsEnum termsEnum;
<span class="fc" id="L3138">      PostingsEnum postingsEnum = null;</span>
<span class="fc" id="L3139">      String segmentName = &quot;segment&quot; + lrc.ord;</span>
<span class="fc" id="L3140">      int segmentNumber = lrc.parent.leaves().size();</span>
<span class="fc" id="L3141">      String[] mutableKey = new String[1];</span>
<span class="fc bfc" id="L3142" title="All 2 branches covered.">      for (ComponentTermVector termVector : termVectorList) {</span>
<span class="pc bpc" id="L3143" title="2 of 6 branches missed.">        if (!termVector.full &amp;&amp; termVector.list == null</span>
            &amp;&amp; (termVector.subComponentFunction.dataCollector.segmentRecomputeKeyList != null
                &amp;&amp; termVector.subComponentFunction.dataCollector.segmentRecomputeKeyList
<span class="fc bfc" id="L3146" title="All 2 branches covered.">                    .containsKey(segmentName))) {</span>
<span class="fc" id="L3147">          Set&lt;String&gt; recomputeKeyList = termVector.subComponentFunction.dataCollector.segmentRecomputeKeyList</span>
<span class="fc" id="L3148">              .get(segmentName);</span>
<span class="pc bpc" id="L3149" title="1 of 2 branches missed.">          if (!recomputeKeyList.isEmpty()) {</span>
<span class="fc" id="L3150">            Map&lt;String, Automaton&gt; automatonMap = MtasToken.createAutomatonMap(</span>
                termVector.prefix, new ArrayList&lt;String&gt;(recomputeKeyList),
<span class="fc" id="L3152">                true);</span>
<span class="fc" id="L3153">            List&lt;CompiledAutomaton&gt; listCompiledAutomata = MtasToken</span>
<span class="fc" id="L3154">                .createAutomata(termVector.prefix, termVector.regexp,</span>
                    automatonMap);
<span class="fc bfc" id="L3156" title="All 2 branches covered.">            for (CompiledAutomaton compiledAutomaton : listCompiledAutomata) {</span>
<span class="fc" id="L3157">              termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="fc" id="L3158">              termVector.subComponentFunction.dataCollector</span>
<span class="fc" id="L3159">                  .initNewList(</span>
                      termVector.subComponentFunction.dataCollector.segmentKeys
<span class="fc" id="L3161">                          .size(),</span>
                      segmentName, segmentNumber, termVector.boundary);
<span class="fc" id="L3163">              RegisterStatus registerStatus = null;</span>
<span class="pc bpc" id="L3164" title="1 of 2 branches missed.">              if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3165" title="1 of 2 branches missed.">                for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3166">                  function.dataCollector.initNewList((int) t.size(),</span>
                      segmentName, segmentNumber, null);
<span class="nc" id="L3168">                }</span>
              }
<span class="pc bpc" id="L3170" title="1 of 2 branches missed.">              if (!docSet.isEmpty()) {</span>
                int termDocId;
<span class="fc bfc" id="L3172" title="All 2 branches covered.">                while ((term = termsEnum.next()) != null) {</span>
<span class="pc bpc" id="L3173" title="1 of 2 branches missed.">                  if (validateTermWithStartValue(term, termVector)) {</span>
<span class="fc" id="L3174">                    termDocId = -1;</span>
<span class="fc" id="L3175">                    mutableKey[0] = null;</span>
                    // compute numbers;
<span class="fc" id="L3177">                    TermvectorNumberBasic numberBasic = computeTermvectorNumberBasic(</span>
                        docSet, termDocId, termsEnum, r, lrc, postingsEnum);
<span class="fc bfc" id="L3179" title="All 2 branches covered.">                    if (numberBasic.docNumber &gt; 0) {</span>
<span class="fc" id="L3180">                      registerStatus = registerValue(term, termVector,</span>
<span class="fc" id="L3181">                          numberBasic, 0, segmentNumber, true, mutableKey);</span>
<span class="fc bfc" id="L3182" title="All 2 branches covered.">                      if (registerStatus != null) {</span>
<span class="fc" id="L3183">                        TermvectorNumberFull numberFull = computeTermvectorNumberFull(</span>
                            docSet, termDocId, termsEnum, lrc, postingsEnum,
                            positionsData);
<span class="pc bpc" id="L3186" title="1 of 2 branches missed.">                        if (numberFull.docNumber &gt; 0) {</span>
<span class="fc" id="L3187">                          registerValue(term, termVector, numberFull,</span>
                              mutableKey);
                        }
                      }
                    }
<span class="fc" id="L3192">                  }</span>
                }
              }
<span class="fc" id="L3195">              termVector.subComponentFunction.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L3196" title="1 of 2 branches missed.">              if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3197" title="1 of 2 branches missed.">                for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3198">                  function.dataCollector.closeNewList();</span>
<span class="nc" id="L3199">                }</span>
              }
<span class="fc" id="L3201">            }</span>
          }
        }
<span class="fc" id="L3204">      }</span>
    }
<span class="fc" id="L3206">  }</span>

  /**
   * Validate term with start value.
   *
   * @param term the term
   * @param termVector the term vector
   * @return true, if successful
   */
  private static boolean validateTermWithStartValue(BytesRef term,
      ComponentTermVector termVector) {
<span class="pc bpc" id="L3217" title="1 of 2 branches missed.">    if (termVector.startValue == null) {</span>
<span class="fc" id="L3218">      return true;</span>
<span class="nc" id="L3219">    } else if (termVector.subComponentFunction.sortType</span>
<span class="nc bnc" id="L3220" title="All 2 branches missed.">        .equals(CodecUtil.SORT_TERM)) {</span>
<span class="nc bnc" id="L3221" title="All 2 branches missed.">      if (term.length &gt; termVector.startValue.length) {</span>
<span class="nc" id="L3222">        byte[] zeroBytes = (new BytesRef(&quot;\u0000&quot;)).bytes;</span>
<span class="nc" id="L3223">        int n = (int) (Math</span>
<span class="nc" id="L3224">            .ceil(((double) (term.length - termVector.startValue.length))</span>
                / zeroBytes.length));
<span class="nc" id="L3226">        byte[] newBytes = new byte[termVector.startValue.length</span>
            + n * zeroBytes.length];
<span class="nc" id="L3228">        System.arraycopy(termVector.startValue.bytes, 0, newBytes, 0,</span>
            termVector.startValue.length);
<span class="nc bnc" id="L3230" title="All 2 branches missed.">        for (int i = 0; i &lt; n; i++) {</span>
<span class="nc" id="L3231">          System.arraycopy(zeroBytes, 0, newBytes,</span>
              termVector.startValue.length + i * zeroBytes.length,
              zeroBytes.length);
        }
<span class="nc" id="L3235">        termVector.startValue = new BytesRef(newBytes);</span>
      }
<span class="nc bnc" id="L3237" title="All 2 branches missed.">      if ((termVector.subComponentFunction.sortDirection.equals(</span>
<span class="nc bnc" id="L3238" title="All 2 branches missed.">          CodecUtil.SORT_ASC) &amp;&amp; (termVector.startValue.compareTo(term) &lt; 0))</span>
          || (termVector.subComponentFunction.sortDirection
<span class="nc bnc" id="L3240" title="All 2 branches missed.">              .equals(CodecUtil.SORT_DESC)</span>
<span class="nc bnc" id="L3241" title="All 2 branches missed.">              &amp;&amp; (termVector.startValue.compareTo(term) &gt; 0))) {</span>
<span class="nc" id="L3242">        return true;</span>
      }
    }
<span class="nc" id="L3245">    return false;</span>
  }

  /**
   * Need second round termvector.
   *
   * @param termVectorList the term vector list
   * @return true, if successful
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static boolean needSecondRoundTermvector(
      List&lt;ComponentTermVector&gt; termVectorList) throws IOException {
<span class="fc" id="L3257">    boolean needSecondRound = false;</span>
<span class="fc bfc" id="L3258" title="All 2 branches covered.">    for (ComponentTermVector termVector : termVectorList) {</span>
<span class="fc bfc" id="L3259" title="All 4 branches covered.">      if (!termVector.full &amp;&amp; termVector.list == null) {</span>
        boolean doCheck;
<span class="fc bfc" id="L3261" title="All 2 branches covered.">        doCheck = termVector.subComponentFunction.dataCollector.segmentRegistration != null</span>
            &amp;&amp; (termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="fc bfc" id="L3263" title="All 2 branches covered.">                .equals(MtasDataCollector.SEGMENT_SORT_ASC)</span>
                || termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="pc bpc" id="L3265" title="2 of 4 branches missed.">                    .equals(MtasDataCollector.SEGMENT_SORT_DESC))</span>
            &amp;&amp; termVector.number &gt; 0;
<span class="fc bfc" id="L3267" title="All 2 branches covered.">        doCheck |= termVector.subComponentFunction.dataCollector.segmentRegistration != null</span>
            &amp;&amp; (termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="pc bpc" id="L3269" title="1 of 2 branches missed.">                .equals(MtasDataCollector.SEGMENT_BOUNDARY_ASC)</span>
                || termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="pc bpc" id="L3271" title="3 of 4 branches missed.">                    .equals(MtasDataCollector.SEGMENT_BOUNDARY_DESC))</span>
            &amp;&amp; termVector.number &gt; 0;
<span class="fc bfc" id="L3273" title="All 2 branches covered.">        if (doCheck) {</span>
<span class="fc" id="L3274">          termVector.subComponentFunction.dataCollector.recomputeSegmentKeys();</span>
<span class="fc" id="L3275">          if (!termVector.subComponentFunction.dataCollector</span>
<span class="fc bfc" id="L3276" title="All 2 branches covered.">              .checkExistenceNecessaryKeys()) {</span>
<span class="fc" id="L3277">            needSecondRound = true;</span>
          }
<span class="fc" id="L3279">          termVector.subComponentFunction.dataCollector.reduceToSegmentKeys();</span>
        }
      }
<span class="fc" id="L3282">    }</span>
<span class="fc" id="L3283">    return needSecondRound;</span>
  }

  /**
   * The Class TermvectorNumberBasic.
   */
  private static class TermvectorNumberBasic {

    /** The value sum. */
    public long[] valueSum;

    /** The doc number. */
    public int docNumber;

    /**
     * Instantiates a new termvector number basic.
     */
<span class="fc" id="L3300">    TermvectorNumberBasic() {</span>
<span class="fc" id="L3301">      valueSum = new long[] { 0 };</span>
<span class="fc" id="L3302">      docNumber = 0;</span>
<span class="fc" id="L3303">    }</span>
  }

  /**
   * The Class TermvectorNumberFull.
   */
  private static class TermvectorNumberFull {

    /** The args. */
    public long[] args;

    /** The positions. */
    public int[] positions;

    /** The doc number. */
    public int docNumber;

    /**
     * Instantiates a new termvector number full.
     *
     * @param maxSize the max size
     */
<span class="fc" id="L3325">    TermvectorNumberFull(int maxSize) {</span>
<span class="fc" id="L3326">      args = new long[maxSize];</span>
<span class="fc" id="L3327">      positions = new int[maxSize];</span>
<span class="fc" id="L3328">      docNumber = 0;</span>
<span class="fc" id="L3329">    }</span>
  }

  /**
   * The Class RegisterStatus.
   */
  private static class RegisterStatus {

    /** The sort value. */
    public long sortValue;

    /** The force. */
    public boolean force;

    /**
     * Instantiates a new register status.
     *
     * @param sortValue the sort value
     * @param force the force
     */
<span class="fc" id="L3349">    RegisterStatus(long sortValue, boolean force) {</span>
<span class="fc" id="L3350">      this.sortValue = sortValue;</span>
<span class="fc" id="L3351">      this.force = force;</span>
<span class="fc" id="L3352">    }</span>
  }

  /**
   * Register value.
   *
   * @param term the term
   * @param termVector the term vector
   * @param number the number
   * @param termNumberMaximum the term number maximum
   * @param segmentNumber the segment number
   * @param forceAccept the force accept
   * @param mutableKey the mutable key
   * @return the register status
   * @throws IOException Signals that an I/O exception has occurred.
   */
  @SuppressWarnings(&quot;unchecked&quot;)
  private static RegisterStatus registerValue(BytesRef term,
      ComponentTermVector termVector, TermvectorNumberBasic number,
      Integer termNumberMaximum, Integer segmentNumber, boolean forceAccept,
      String[] mutableKey) throws IOException {
<span class="fc" id="L3373">    long value = termVector.subComponentFunction.parserFunction</span>
<span class="fc" id="L3374">        .getValueLong(number.valueSum, 0);</span>
<span class="fc" id="L3375">    long sortValue = 0;</span>
<span class="fc" id="L3376">    if (termVector.subComponentFunction.sortType</span>
<span class="fc bfc" id="L3377" title="All 2 branches covered.">        .equals(CodecUtil.STATS_TYPE_SUM)) {</span>
<span class="fc" id="L3378">      sortValue = value;</span>
<span class="fc" id="L3379">    } else if (termVector.subComponentFunction.sortType</span>
<span class="pc bpc" id="L3380" title="1 of 2 branches missed.">        .equals(CodecUtil.STATS_TYPE_N)) {</span>
<span class="nc" id="L3381">      sortValue = number.docNumber;</span>
    }
<span class="fc" id="L3383">    boolean addItem = false;</span>
<span class="fc" id="L3384">    boolean addItemForced = false;</span>
<span class="fc" id="L3385">    MtasDataCollector&lt;Long, ?&gt; dataCollector = (MtasDataCollector&lt;Long, ?&gt;) termVector.subComponentFunction.dataCollector;</span>
    // sort on term
<span class="fc bfc" id="L3387" title="All 2 branches covered.">    if (termVector.subComponentFunction.sortType.equals(CodecUtil.SORT_TERM)) {</span>
<span class="fc" id="L3388">      addItem = true;</span>
<span class="fc" id="L3389">      addItemForced = true;</span>
      // sort on sum or n
<span class="fc" id="L3391">    } else if (termVector.subComponentFunction.sortType</span>
<span class="pc bpc" id="L3392" title="1 of 2 branches missed.">        .equals(CodecUtil.STATS_TYPE_SUM)</span>
        || termVector.subComponentFunction.sortType
<span class="nc bnc" id="L3394" title="All 2 branches missed.">            .equals(CodecUtil.STATS_TYPE_N)) {</span>
      // always accept
<span class="fc bfc" id="L3396" title="All 2 branches covered.">      if (forceAccept) {</span>
<span class="fc" id="L3397">        addItem = true;</span>
<span class="fc" id="L3398">        addItemForced = addItem;</span>
        // check boundary
<span class="pc bpc" id="L3400" title="1 of 2 branches missed.">      } else if (termVector.boundaryRegistration) {</span>
<span class="nc" id="L3401">        addItem = dataCollector.validateSegmentBoundary(sortValue);</span>
<span class="nc bnc" id="L3402" title="All 2 branches missed.">        if (addItem) {</span>
<span class="nc bnc" id="L3403" title="All 2 branches missed.">          if (mutableKey[0] == null) {</span>
<span class="nc" id="L3404">            mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
          }
<span class="nc" id="L3406">          String segmentStatus = dataCollector.validateSegmentValue(</span>
<span class="nc" id="L3407">              mutableKey[0], sortValue, termNumberMaximum, segmentNumber,</span>
              false);
<span class="nc bnc" id="L3409" title="All 2 branches missed.">          if (segmentStatus != null) {</span>
<span class="nc bnc" id="L3410" title="All 2 branches missed.">            if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY)) {</span>
<span class="nc" id="L3411">              addItemForced = true;</span>
            }
          } else {
            // shouldn't happen
          }
<span class="nc" id="L3416">        }</span>
        // no boundary
      } else {
<span class="fc" id="L3419">        String segmentStatus = dataCollector.validateSegmentValue(sortValue,</span>
<span class="fc" id="L3420">            termNumberMaximum, segmentNumber);</span>
<span class="fc bfc" id="L3421" title="All 2 branches covered.">        if (segmentStatus != null) {</span>
          boolean possibleAddItem;
<span class="fc bfc" id="L3423" title="All 2 branches covered.">          if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY_OR_NEW)) {</span>
<span class="fc" id="L3424">            possibleAddItem = true;</span>
<span class="fc" id="L3425">          } else if (segmentStatus</span>
<span class="pc bpc" id="L3426" title="1 of 2 branches missed.">              .equals(MtasDataCollector.SEGMENT_POSSIBLE_KEY)) {</span>
<span class="fc" id="L3427">            mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
<span class="fc" id="L3428">            segmentStatus = dataCollector.validateSegmentValue(mutableKey[0],</span>
<span class="fc" id="L3429">                sortValue, termNumberMaximum, segmentNumber, true);</span>
<span class="fc bfc" id="L3430" title="All 2 branches covered.">            if (segmentStatus != null) {</span>
<span class="fc" id="L3431">              possibleAddItem = true;</span>
            } else {
<span class="fc" id="L3433">              possibleAddItem = false;</span>
            }
          } else {
            // should never happen?
<span class="nc" id="L3437">            possibleAddItem = false;</span>
          }
          // further checks, passed initial
<span class="fc bfc" id="L3440" title="All 2 branches covered.">          if (possibleAddItem) {</span>
<span class="fc bfc" id="L3441" title="All 2 branches covered.">            if (mutableKey[0] == null) {</span>
<span class="fc" id="L3442">              mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
            }
<span class="fc" id="L3444">            segmentStatus = dataCollector.validateSegmentValue(mutableKey[0],</span>
<span class="fc" id="L3445">                sortValue, termNumberMaximum, segmentNumber, false);</span>
<span class="pc bpc" id="L3446" title="1 of 2 branches missed.">            if (segmentStatus != null) {</span>
<span class="fc" id="L3447">              addItem = true;</span>
<span class="fc bfc" id="L3448" title="All 2 branches covered.">              if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY)) {</span>
<span class="fc" id="L3449">                addItemForced = true;</span>
              }
            }
          }
<span class="fc" id="L3453">        } else {</span>
<span class="fc" id="L3454">          addItem = false;</span>
        }
<span class="fc" id="L3456">      }</span>
      // don't sort?
    } else {
<span class="nc" id="L3459">      addItem = false;</span>
    }
<span class="fc bfc" id="L3461" title="All 2 branches covered.">    if (addItem) {</span>
<span class="fc" id="L3462">      boolean computeFull = false;</span>
<span class="fc bfc" id="L3463" title="All 2 branches covered.">      if (mutableKey[0] == null) {</span>
<span class="fc" id="L3464">        mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
      }
      // check dataCollector type
<span class="fc" id="L3467">      if (termVector.subComponentFunction.statsType</span>
<span class="fc bfc" id="L3468" title="All 2 branches covered.">          .equals(CodecUtil.STATS_BASIC)) {</span>
<span class="fc" id="L3469">        dataCollector.add(mutableKey[0], value, number.docNumber);</span>
      } else {
<span class="fc" id="L3471">        computeFull = true;</span>
      }
      // functions
<span class="pc bpc" id="L3474" title="1 of 2 branches missed.">      if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3475" title="1 of 2 branches missed.">        for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc bnc" id="L3476" title="All 2 branches missed.">          if (function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L3477" title="All 2 branches missed.">              &amp;&amp; !function.parserFunction.needPositions()</span>
<span class="nc bnc" id="L3478" title="All 2 branches missed.">              &amp;&amp; function.statsType.equals(CodecUtil.STATS_BASIC)) {</span>
<span class="nc bnc" id="L3479" title="All 2 branches missed.">            if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L3480">              long valueFunction = function.parserFunction</span>
<span class="nc" id="L3481">                  .getValueLong(number.valueSum, 0);</span>
<span class="nc" id="L3482">              function.dataCollector.add(mutableKey[0], valueFunction,</span>
                  number.docNumber);
<span class="nc bnc" id="L3484" title="All 2 branches missed.">            } else if (function.dataType.equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L3485">              double valueFunction = function.parserFunction</span>
<span class="nc" id="L3486">                  .getValueDouble(number.valueSum, 0);</span>
<span class="nc" id="L3487">              function.dataCollector.add(mutableKey[0], valueFunction,</span>
                  number.docNumber);
<span class="nc" id="L3489">            }</span>
          } else {
<span class="nc" id="L3491">            computeFull = true;</span>
          }
<span class="nc" id="L3493">        }</span>
      }
      // add as full?
<span class="fc bfc" id="L3496" title="All 2 branches covered.">      return computeFull ? new RegisterStatus(sortValue, addItemForced) : null;</span>
    } else {
<span class="fc" id="L3498">      return null;</span>
    }
  }

  /**
   * Preliminary register value.
   *
   * @param term the term
   * @param termVector the term vector
   * @param number the number
   * @param termNumberMaximum the term number maximum
   * @param segmentNumber the segment number
   * @param mutableKey the mutable key
   * @return true, if successful
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static boolean preliminaryRegisterValue(BytesRef term,
      ComponentTermVector termVector, TermvectorNumberBasic number,
      Integer termNumberMaximum, Integer segmentNumber, String[] mutableKey)
      throws IOException {
<span class="nc" id="L3518">    long sortValue = 0;</span>
<span class="nc" id="L3519">    if (termVector.subComponentFunction.sortDirection</span>
<span class="nc bnc" id="L3520" title="All 2 branches missed.">        .equals(CodecUtil.SORT_DESC)</span>
        &amp;&amp; termVector.subComponentFunction.sortType
<span class="nc bnc" id="L3522" title="All 2 branches missed.">            .equals(CodecUtil.STATS_TYPE_SUM)) {</span>
<span class="nc" id="L3523">      sortValue = termVector.subComponentFunction.parserFunction</span>
<span class="nc" id="L3524">          .getValueLong(number.valueSum, 0);</span>
<span class="nc" id="L3525">    } else if (termVector.subComponentFunction.sortDirection</span>
<span class="nc bnc" id="L3526" title="All 2 branches missed.">        .equals(CodecUtil.SORT_DESC)</span>
        &amp;&amp; termVector.subComponentFunction.sortType
<span class="nc bnc" id="L3528" title="All 2 branches missed.">            .equals(CodecUtil.STATS_TYPE_N)) {</span>
<span class="nc" id="L3529">      sortValue = number.docNumber;</span>
    } else {
<span class="nc" id="L3531">      return true;</span>
    }
<span class="nc" id="L3533">    MtasDataCollector&lt;Long, ?&gt; dataCollector = (MtasDataCollector&lt;Long, ?&gt;) termVector.subComponentFunction.dataCollector;</span>
<span class="nc bnc" id="L3534" title="All 2 branches missed.">    if (termVector.boundaryRegistration) {</span>
<span class="nc" id="L3535">      return dataCollector.validateSegmentBoundary(sortValue);</span>
    } else {
<span class="nc" id="L3537">      String segmentStatus = dataCollector.validateSegmentValue(sortValue,</span>
<span class="nc" id="L3538">          termNumberMaximum, segmentNumber);</span>
<span class="nc bnc" id="L3539" title="All 2 branches missed.">      if (segmentStatus != null) {</span>
<span class="nc bnc" id="L3540" title="All 2 branches missed.">        if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY_OR_NEW)) {</span>
<span class="nc" id="L3541">          return true;</span>
<span class="nc" id="L3542">        } else if (segmentStatus</span>
<span class="nc bnc" id="L3543" title="All 2 branches missed.">            .equals(MtasDataCollector.SEGMENT_POSSIBLE_KEY)) {</span>
<span class="nc" id="L3544">          mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
<span class="nc" id="L3545">          segmentStatus = dataCollector.validateSegmentValue(mutableKey[0],</span>
<span class="nc" id="L3546">              sortValue, termNumberMaximum, segmentNumber, true);</span>
<span class="nc bnc" id="L3547" title="All 2 branches missed.">          return segmentStatus != null;</span>
        } else {
          // should never happen?
<span class="nc" id="L3550">          return false;</span>
        }
      } else {
<span class="nc" id="L3553">        return false;</span>
      }
    }
  }

  /**
   * Register value.
   *
   * @param term the term
   * @param termVector the term vector
   * @param number the number
   * @param mutableKey the mutable key
   * @throws IOException Signals that an I/O exception has occurred.
   */
  @SuppressWarnings(&quot;unchecked&quot;)
  private static void registerValue(BytesRef term,
      ComponentTermVector termVector, TermvectorNumberFull number,
      String[] mutableKey) throws IOException {
<span class="pc bpc" id="L3571" title="1 of 2 branches missed.">    if (number.docNumber &gt; 0) {</span>
<span class="fc bfc" id="L3572" title="All 2 branches covered.">      if (mutableKey[0] == null) {</span>
<span class="fc" id="L3573">        mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
      }
<span class="fc" id="L3575">      MtasDataCollector&lt;Long, ?&gt; dataCollector = (MtasDataCollector&lt;Long, ?&gt;) termVector.subComponentFunction.dataCollector;</span>
<span class="fc" id="L3576">      long[] valuesLong = new long[number.docNumber];</span>
<span class="fc bfc" id="L3577" title="All 2 branches covered.">      for (int i = 0; i &lt; number.docNumber; i++) {</span>
        try {
<span class="fc" id="L3579">          valuesLong[i] = termVector.subComponentFunction.parserFunction</span>
<span class="fc" id="L3580">              .getValueLong(new long[] { number.args[i] }, number.positions[i]);</span>
<span class="nc" id="L3581">        } catch (IOException e) {</span>
<span class="nc" id="L3582">          log.debug(e);</span>
<span class="nc" id="L3583">          dataCollector.error(mutableKey[0], e.getMessage());</span>
<span class="fc" id="L3584">        }</span>
      }
<span class="fc" id="L3586">      if (!termVector.subComponentFunction.statsType</span>
<span class="pc bpc" id="L3587" title="1 of 2 branches missed.">          .equals(CodecUtil.STATS_BASIC)) {</span>
<span class="fc" id="L3588">        dataCollector.add(mutableKey[0], valuesLong, valuesLong.length);</span>
      }
<span class="pc bpc" id="L3590" title="1 of 2 branches missed.">      for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc bnc" id="L3591" title="All 2 branches missed.">        if (!function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L3592" title="All 2 branches missed.">            || function.parserFunction.needPositions()</span>
<span class="nc bnc" id="L3593" title="All 2 branches missed.">            || !function.statsType.equals(CodecUtil.STATS_BASIC)) {</span>
<span class="nc bnc" id="L3594" title="All 2 branches missed.">          if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L3595">            valuesLong = new long[number.docNumber];</span>
<span class="nc bnc" id="L3596" title="All 2 branches missed.">            for (int i = 0; i &lt; number.docNumber; i++) {</span>
              try {
<span class="nc" id="L3598">                valuesLong[i] = function.parserFunction.getValueLong(</span>
                    new long[] { number.args[i] }, number.positions[i]);
<span class="nc" id="L3600">              } catch (IOException e) {</span>
<span class="nc" id="L3601">                log.debug(e);</span>
<span class="nc" id="L3602">                function.dataCollector.error(mutableKey[0], e.getMessage());</span>
<span class="nc" id="L3603">              }</span>
            }
<span class="nc" id="L3605">            function.dataCollector.add(mutableKey[0], valuesLong,</span>
                valuesLong.length);
<span class="nc bnc" id="L3607" title="All 2 branches missed.">          } else if (function.dataType.equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L3608">            double[] valuesDouble = new double[number.docNumber];</span>
<span class="nc bnc" id="L3609" title="All 2 branches missed.">            for (int i = 0; i &lt; number.docNumber; i++) {</span>
              try {
<span class="nc" id="L3611">                valuesDouble[i] = function.parserFunction.getValueDouble(</span>
                    new long[] { number.args[i] }, number.positions[i]);
<span class="nc" id="L3613">              } catch (IOException e) {</span>
<span class="nc" id="L3614">                log.debug(e);</span>
<span class="nc" id="L3615">                function.dataCollector.error(mutableKey[0], e.getMessage());</span>
<span class="nc" id="L3616">              }</span>
            }
<span class="nc" id="L3618">            function.dataCollector.add(mutableKey[0], valuesDouble,</span>
                valuesDouble.length);
          }
        }
<span class="nc" id="L3622">      }</span>
    }
<span class="fc" id="L3624">  }</span>

  /**
   * Compute termvector number basic.
   *
   * @param termsEnum the terms enum
   * @param r the r
   * @return the termvector number basic
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static TermvectorNumberBasic computeTermvectorNumberBasic(
      TermsEnum termsEnum, LeafReader r) throws IOException {
<span class="fc" id="L3636">    TermvectorNumberBasic result = new TermvectorNumberBasic();</span>
<span class="pc bpc" id="L3637" title="1 of 2 branches missed.">    boolean hasDeletedDocuments = (r.getLiveDocs() != null);</span>
<span class="pc bpc" id="L3638" title="1 of 2 branches missed.">    if (!hasDeletedDocuments) {</span>
<span class="fc" id="L3639">      result.valueSum[0] = termsEnum.totalTermFreq();</span>
<span class="fc" id="L3640">      result.docNumber = termsEnum.docFreq();</span>
<span class="pc bpc" id="L3641" title="1 of 2 branches missed.">      if (result.valueSum[0] &gt; -1) {</span>
<span class="fc" id="L3642">        return result;</span>
      }
    }
<span class="nc" id="L3645">    throw new IOException(&quot;should not call this&quot;);</span>
  }

  /**
   * Compute termvector number basic.
   *
   * @param docSet the doc set
   * @param termDocId the term doc id
   * @param termsEnum the terms enum
   * @param r the r
   * @param lrc the lrc
   * @param postingsEnum the postings enum
   * @return the termvector number basic
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static TermvectorNumberBasic computeTermvectorNumberBasic(
      List&lt;Integer&gt; docSet, int termDocId, TermsEnum termsEnum, LeafReader r,
      LeafReaderContext lrc, PostingsEnum postingsEnum) throws IOException {
<span class="fc" id="L3663">    TermvectorNumberBasic result = new TermvectorNumberBasic();</span>
<span class="fc bfc" id="L3664" title="All 2 branches covered.">    boolean hasDeletedDocuments = (r.getLiveDocs() != null);</span>
<span class="pc bpc" id="L3665" title="1 of 4 branches missed.">    if ((docSet.size() == r.numDocs()) &amp;&amp; !hasDeletedDocuments) {</span>
      try {
<span class="fc" id="L3667">        return computeTermvectorNumberBasic(termsEnum, r);</span>
<span class="nc" id="L3668">      } catch (IOException e) {</span>
<span class="nc" id="L3669">        log.debug(&quot;problem&quot;, e);</span>
        // problem
      }
    }
<span class="fc" id="L3673">    result.docNumber = 0;</span>
<span class="fc" id="L3674">    result.valueSum[0] = 0;</span>
<span class="fc" id="L3675">    int localTermDocId = termDocId;</span>
<span class="fc" id="L3676">    Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="fc" id="L3677">    postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.FREQS);</span>
    int docId;
<span class="fc bfc" id="L3679" title="All 2 branches covered.">    while (docIterator.hasNext()) {</span>
<span class="fc" id="L3680">      docId = docIterator.next() - lrc.docBase;</span>
<span class="pc bpc" id="L3681" title="2 of 4 branches missed.">      if (docId &gt;= localTermDocId &amp;&amp; ((docId == localTermDocId)</span>
<span class="fc bfc" id="L3682" title="All 2 branches covered.">          || ((localTermDocId = postingsEnum.advance(docId)) == docId))) {</span>
<span class="fc" id="L3683">        result.docNumber++;</span>
<span class="fc" id="L3684">        result.valueSum[0] += postingsEnum.freq();</span>
      }
<span class="pc bpc" id="L3686" title="1 of 2 branches missed.">      if (localTermDocId == DocIdSetIterator.NO_MORE_DOCS) {</span>
<span class="nc" id="L3687">        break;</span>
      }
    }
<span class="fc" id="L3690">    return result;</span>
  }

  /**
   * Compute termvector number full.
   *
   * @param docSet the doc set
   * @param termDocId the term doc id
   * @param termsEnum the terms enum
   * @param lrc the lrc
   * @param postingsEnum the postings enum
   * @param positionsData the positions data
   * @return the termvector number full
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private static TermvectorNumberFull computeTermvectorNumberFull(
      List&lt;Integer&gt; docSet, int termDocId, TermsEnum termsEnum,
      LeafReaderContext lrc, PostingsEnum postingsEnum,
      Map&lt;Integer, Integer&gt; positionsData) throws IOException {
<span class="fc" id="L3709">    TermvectorNumberFull result = new TermvectorNumberFull(docSet.size());</span>
<span class="fc" id="L3710">    Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="fc" id="L3711">    int localTermDocId = termDocId;</span>
<span class="fc" id="L3712">    postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.FREQS);</span>
<span class="fc bfc" id="L3713" title="All 2 branches covered.">    while (docIterator.hasNext()) {</span>
<span class="fc" id="L3714">      int docId = docIterator.next() - lrc.docBase;</span>
<span class="fc bfc" id="L3715" title="All 4 branches covered.">      if (docId &gt;= localTermDocId &amp;&amp; ((docId == localTermDocId)</span>
<span class="fc bfc" id="L3716" title="All 2 branches covered.">          || ((localTermDocId = postingsEnum.advance(docId)) == docId))) {</span>
<span class="fc" id="L3717">        result.args[result.docNumber] = postingsEnum.freq();</span>
<span class="pc bpc" id="L3718" title="1 of 2 branches missed.">        result.positions[result.docNumber] = (positionsData == null) ? 0</span>
<span class="pc" id="L3719">            : positionsData.get(docId + lrc.docBase);</span>
<span class="fc" id="L3720">        result.docNumber++;</span>
      }
<span class="fc" id="L3722">    }</span>
<span class="fc" id="L3723">    return result;</span>
  }

}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.7.9.201702052155</span></div></body></html>