<?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="../.resources/report.css" type="text/css"/><link rel="shortcut icon" href="../.resources/report.gif" type="image/gif"/><title>CodecCollector.java</title><link rel="stylesheet" href="../.resources/prettify.css" type="text/css"/><script type="text/javascript" src="../.resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../.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.Comparator;
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.Entry;
import java.util.TreeMap;
import java.util.TreeSet;
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.ComponentJoin;
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.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.
 */
<span class="nc" id="L80">public class CodecCollector {</span>

  /**
   * Collect.
   *
   * @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, ArrayList&lt;Integer&gt; fullDocList,
      ArrayList&lt;Integer&gt; fullDocSet, ComponentField fieldInfo,
      HashMap&lt;MtasSpanQuery, SpanWeight&gt; spansQueryWeight)
      throws IllegalAccessException, IllegalArgumentException,
      InvocationTargetException, IOException {

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

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

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

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

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

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

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

  public static void collectJoin(IndexReader reader, ArrayList&lt;Integer&gt; docSet,
      ComponentJoin joinInfo) throws IOException {
<span class="nc" id="L205">    BytesRef term = null;</span>
<span class="nc" id="L206">    PostingsEnum postingsEnum = null;</span>
    Integer docId;
<span class="nc" id="L208">    Integer termDocId = -1;</span>
    Terms terms;
    LeafReaderContext lrc;
    LeafReader r;
<span class="nc" id="L212">    ListIterator&lt;LeafReaderContext&gt; iterator = reader.leaves().listIterator();</span>
<span class="nc bnc" id="L213" title="All 2 branches missed.">    while (iterator.hasNext()) {</span>
<span class="nc" id="L214">      lrc = iterator.next();</span>
<span class="nc" id="L215">      r = lrc.reader();</span>
<span class="nc bnc" id="L216" title="All 2 branches missed.">      for (String field : joinInfo.fields()) {</span>
<span class="nc bnc" id="L217" title="All 2 branches missed.">        if ((terms = r.fields().terms(field)) != null) {</span>
<span class="nc" id="L218">          TermsEnum termsEnum = terms.iterator();</span>
<span class="nc" id="L219">          termDocId = -1;</span>
<span class="nc bnc" id="L220" title="All 2 branches missed.">          while ((term = termsEnum.next()) != null) {</span>
<span class="nc" id="L221">            Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="nc" id="L222">            postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);</span>
<span class="nc bnc" id="L223" title="All 2 branches missed.">            while (docIterator.hasNext()) {</span>
<span class="nc" id="L224">              docId = docIterator.next() - lrc.docBase;</span>
<span class="nc bnc" id="L225" title="All 4 branches missed.">              if ((docId &gt;= termDocId) &amp;&amp; ((docId.equals(termDocId))</span>
<span class="nc" id="L226">                  || ((termDocId = postingsEnum.advance(docId))</span>
<span class="nc bnc" id="L227" title="All 2 branches missed.">                      .equals(docId)))) {</span>
<span class="nc" id="L228">                joinInfo.add(term.utf8ToString());</span>
<span class="nc" id="L229">                break;</span>
              }
            }
<span class="nc" id="L232">          }</span>
        }
<span class="nc" id="L234">      }</span>
    }
<span class="nc" id="L236">  }</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(
      HashMap&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="L273">    boolean needSpans = false;</span>
<span class="fc" id="L274">    boolean needPositions = false;</span>
<span class="fc" id="L275">    boolean needTokens = false;</span>

    // results
<span class="fc" id="L278">    HashMap&lt;Integer, Integer&gt; positionsData = null;</span>
<span class="fc" id="L279">    HashMap&lt;Integer, Integer&gt; tokensData = null;</span>
<span class="fc" id="L280">    HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, Integer&gt;&gt; spansNumberData = null;</span>
<span class="fc" id="L281">    HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt;&gt; spansMatchData = null;</span>
<span class="fc" id="L282">    HashMap&lt;String, TreeMap&lt;String, int[]&gt;&gt; facetData = null;</span>
<span class="fc" id="L283">    HashMap&lt;String, String&gt; facetDataType = null;</span>

    // collect position stats
<span class="fc bfc" id="L286" title="All 2 branches covered.">    if (!fieldInfo.statsPositionList.isEmpty()) {</span>
<span class="fc" id="L287">      needPositions = true;</span>
    }
    // collect token stats
<span class="fc bfc" id="L290" title="All 2 branches covered.">    if (!fieldInfo.statsTokenList.isEmpty()) {</span>
<span class="fc" id="L291">      needTokens = true;</span>
    }
<span class="fc bfc" id="L293" title="All 2 branches covered.">    if (!fieldInfo.termVectorList.isEmpty()) {</span>
<span class="fc bfc" id="L294" title="All 2 branches covered.">      for (ComponentTermVector ctv : fieldInfo.termVectorList) {</span>
<span class="pc bpc" id="L295" title="3 of 4 branches missed.">        needPositions = !needPositions ? (ctv.functions == null</span>
<span class="nc" id="L296">            ? ctv.subComponentFunction.parserFunction.needPositions()</span>
<span class="pc" id="L297">            : ctv.functionNeedPositions()) : needPositions;</span>
<span class="fc" id="L298">      }</span>
    }

    // compute from spans for selected docs
<span class="fc bfc" id="L302" title="All 2 branches covered.">    if (!fieldInfo.spanQueryList.isEmpty()) {</span>
      // check for statsSpans
<span class="fc" id="L304">      spansNumberData = new HashMap&lt;&gt;();</span>
<span class="fc" id="L305">      spansMatchData = new HashMap&lt;&gt;();</span>
<span class="fc" id="L306">      facetData = new HashMap&lt;&gt;();</span>
<span class="fc" id="L307">      facetDataType = new HashMap&lt;&gt;();</span>
      // spans
<span class="pc bpc" id="L309" title="1 of 2 branches missed.">      if (!fieldInfo.statsSpanList.isEmpty()) {</span>
<span class="fc bfc" id="L310" title="All 2 branches covered.">        for (ComponentSpan cs : fieldInfo.statsSpanList) {</span>
<span class="fc bfc" id="L311" title="All 2 branches covered.">          needPositions = (!needPositions) ? cs.parser.needPositions()</span>
              : needPositions;
<span class="fc bfc" id="L313" title="All 2 branches covered.">          needPositions = (!needPositions) ? cs.functionNeedPositions()</span>
              : needPositions;
<span class="pc bpc" id="L315" title="1 of 4 branches missed.">          needSpans = (!needSpans) ? cs.parser.needArgumentsNumber() &gt; 0</span>
              : needSpans;
<span class="fc" id="L317">          HashSet&lt;Integer&gt; arguments = cs.parser.needArgument();</span>
<span class="fc" id="L318">          arguments.addAll(cs.functionNeedArguments());</span>
<span class="fc bfc" id="L319" title="All 2 branches covered.">          for (int a : arguments) {</span>
<span class="pc bpc" id="L320" title="1 of 2 branches missed.">            if (cs.queries.length &gt; a) {</span>
<span class="fc" id="L321">              MtasSpanQuery q = cs.queries[a];</span>
<span class="fc bfc" id="L322" title="All 2 branches covered.">              if (!spansNumberData.containsKey(q)) {</span>
<span class="fc" id="L323">                spansNumberData.put(q, new HashMap&lt;Integer, Integer&gt;());</span>
              }
            }
<span class="fc" id="L326">          }</span>
<span class="fc" id="L327">        }</span>
      }
      // kwic
<span class="pc bpc" id="L330" title="1 of 2 branches missed.">      if (!fieldInfo.kwicList.isEmpty()) {</span>
<span class="nc" id="L331">        needSpans = true;</span>
<span class="nc bnc" id="L332" title="All 2 branches missed.">        for (ComponentKwic ck : fieldInfo.kwicList) {</span>
<span class="nc bnc" id="L333" title="All 2 branches missed.">          if (!spansMatchData.containsKey(ck.query)) {</span>
<span class="nc" id="L334">            spansMatchData.put(ck.query,</span>
                new HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt;());
          }
<span class="nc" id="L337">        }</span>
      }
      // list
<span class="pc bpc" id="L340" title="1 of 2 branches missed.">      if (!fieldInfo.listList.isEmpty()) {</span>
<span class="nc" id="L341">        needSpans = true;</span>
<span class="nc bnc" id="L342" title="All 2 branches missed.">        for (ComponentList cl : fieldInfo.listList) {</span>
<span class="nc bnc" id="L343" title="All 2 branches missed.">          if (!spansMatchData.containsKey(cl.spanQuery)) {</span>
<span class="nc bnc" id="L344" title="All 2 branches missed.">            if (cl.number &gt; 0) {</span>
              // only if needed
<span class="nc bnc" id="L346" title="All 2 branches missed.">              if (cl.position &lt; (cl.start + cl.number)) {</span>
<span class="nc" id="L347">                spansMatchData.put(cl.spanQuery,</span>
                    new HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt;());
              } else {
<span class="nc" id="L350">                spansNumberData.put(cl.spanQuery,</span>
                    new HashMap&lt;Integer, Integer&gt;());
              }
<span class="nc bnc" id="L353" title="All 2 branches missed.">            } else if (!spansNumberData.containsKey(cl.spanQuery)) {</span>
<span class="nc" id="L354">              spansNumberData.put(cl.spanQuery,</span>
                  new HashMap&lt;Integer, Integer&gt;());
            }
          }
<span class="nc" id="L358">        }</span>
      }
      // group
<span class="fc bfc" id="L361" title="All 2 branches covered.">      if (!fieldInfo.groupList.isEmpty()) {</span>
<span class="fc" id="L362">        needSpans = true;</span>
<span class="fc bfc" id="L363" title="All 2 branches covered.">        for (ComponentGroup cg : fieldInfo.groupList) {</span>
<span class="pc bpc" id="L364" title="1 of 2 branches missed.">          if (!spansMatchData.containsKey(cg.spanQuery)) {</span>
<span class="fc" id="L365">            spansMatchData.put(cg.spanQuery,</span>
                new HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt;());
          }
<span class="fc" id="L368">        }</span>
      }
      // facet
<span class="pc bpc" id="L371" title="1 of 2 branches missed.">      if (!fieldInfo.facetList.isEmpty()) {</span>
<span class="nc bnc" id="L372" title="All 2 branches missed.">        for (ComponentFacet cf : fieldInfo.facetList) {</span>
<span class="nc bnc" id="L373" title="All 2 branches missed.">          needPositions = !needPositions ? cf.baseParserNeedPositions()</span>
              : needPositions;
<span class="nc bnc" id="L375" title="All 2 branches missed.">          needPositions = !needPositions ? cf.functionNeedPositions()</span>
              : needPositions;
<span class="nc bnc" id="L377" title="All 2 branches missed.">          for (int i = 0; i &lt; cf.baseFields.length; i++) {</span>
<span class="nc bnc" id="L378" title="All 4 branches missed.">            needSpans = !needSpans ? cf.baseParsers[i].needArgumentsNumber() &gt; 0</span>
                : needSpans;
<span class="nc" id="L380">            HashSet&lt;Integer&gt; arguments = cf.baseParsers[i].needArgument();</span>
<span class="nc bnc" id="L381" title="All 2 branches missed.">            for (int a : arguments) {</span>
<span class="nc bnc" id="L382" title="All 2 branches missed.">              if (cf.spanQueries.length &gt; a) {</span>
<span class="nc" id="L383">                MtasSpanQuery q = cf.spanQueries[a];</span>
<span class="nc bnc" id="L384" title="All 2 branches missed.">                if (!spansNumberData.containsKey(q)) {</span>
<span class="nc" id="L385">                  spansNumberData.put(q, new HashMap&lt;Integer, Integer&gt;());</span>
                }
              }
<span class="nc" id="L388">            }</span>
<span class="nc bnc" id="L389" title="All 2 branches missed.">            for (MtasFunctionParserFunction function : cf.baseFunctionParserFunctions[i]) {</span>
<span class="nc bnc" id="L390" title="All 4 branches missed.">              needSpans = !needSpans ? function.needArgumentsNumber() &gt; 0</span>
                  : needSpans;
<span class="nc" id="L392">              arguments = function.needArgument();</span>
<span class="nc bnc" id="L393" title="All 2 branches missed.">              for (int a : arguments) {</span>
<span class="nc bnc" id="L394" title="All 2 branches missed.">                if (cf.spanQueries.length &gt; a) {</span>
<span class="nc" id="L395">                  MtasSpanQuery q = cf.spanQueries[a];</span>
<span class="nc bnc" id="L396" title="All 2 branches missed.">                  if (!spansNumberData.containsKey(q)) {</span>
<span class="nc" id="L397">                    spansNumberData.put(q, new HashMap&lt;Integer, Integer&gt;());</span>
                  }
                }
<span class="nc" id="L400">              }</span>
            }
<span class="nc bnc" id="L402" title="All 2 branches missed.">            if (!facetData.containsKey(cf.baseFields[i])) {</span>
<span class="nc" id="L403">              facetData.put(cf.baseFields[i], new TreeMap&lt;String, int[]&gt;());</span>
<span class="nc" id="L404">              facetDataType.put(cf.baseFields[i], cf.baseFieldTypes[i]);</span>
            }
          }
<span class="nc" id="L407">        }</span>
      }
      // termvector
<span class="pc bpc" id="L410" title="1 of 2 branches missed.">      if (fieldInfo.termVectorList.size() &gt; 0) {</span>
<span class="nc bnc" id="L411" title="All 2 branches missed.">        for (ComponentTermVector ctv : fieldInfo.termVectorList) {</span>
<span class="nc bnc" id="L412" title="All 2 branches missed.">          if ((ctv.subComponentFunction.parserFunction != null</span>
<span class="nc bnc" id="L413" title="All 4 branches missed.">              &amp;&amp; ctv.subComponentFunction.parserFunction.needPositions())</span>
<span class="nc bnc" id="L414" title="All 2 branches missed.">              || (ctv.functions != null &amp;&amp; ctv.functionNeedPositions())) {</span>
<span class="nc" id="L415">            needPositions = true;</span>
          }
<span class="nc" id="L417">        }</span>
      }
    }

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

      // collect values for facetFields
<span class="pc bpc" id="L426" title="1 of 2 branches missed.">      for (Entry&lt;String,TreeMap&lt;String, int[]&gt;&gt; entry : facetData.entrySet()) {</span>
<span class="nc" id="L427">        Terms fft = r.terms(entry.getKey());</span>
<span class="nc bnc" id="L428" title="All 2 branches missed.">        if (fft != null) {</span>
<span class="nc" id="L429">          TermsEnum termsEnum = fft.iterator();</span>
<span class="nc" id="L430">          BytesRef term = null;</span>
<span class="nc" id="L431">          PostingsEnum postingsEnum = null;</span>
<span class="nc" id="L432">          TreeMap&lt;String, int[]&gt; facetDataList = entry.getValue();</span>
<span class="nc bnc" id="L433" title="All 2 branches missed.">          while ((term = termsEnum.next()) != null) {</span>
            int docId;
<span class="nc" id="L435">            int termDocId = -1;</span>
<span class="nc" id="L436">            int[] facetDataSublist = new int[docSet.size()];</span>
<span class="nc" id="L437">            int facetDataSublistCounter = 0;</span>
<span class="nc" id="L438">            Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="nc" id="L439">            postingsEnum = termsEnum.postings(postingsEnum);</span>
<span class="nc bnc" id="L440" title="All 2 branches missed.">            while (docIterator.hasNext()) {</span>
<span class="nc" id="L441">              docId = docIterator.next() - lrc.docBase;</span>
<span class="nc bnc" id="L442" title="All 2 branches missed.">              if (docId &gt;= termDocId) {</span>
<span class="nc bnc" id="L443" title="All 2 branches missed.">                if ((docId == termDocId)</span>
<span class="nc bnc" id="L444" title="All 2 branches missed.">                    || ((termDocId = postingsEnum.advance(docId)) == docId)) {</span>
<span class="nc" id="L445">                  facetDataSublist[facetDataSublistCounter] = docId</span>
                      + lrc.docBase;
<span class="nc" id="L447">                  facetDataSublistCounter++;</span>
                }
              }
            }
<span class="nc bnc" id="L451" title="All 2 branches missed.">            if (facetDataSublistCounter &gt; 0) {</span>
<span class="nc" id="L452">              String termValue = null;</span>
<span class="nc" id="L453">              if (facetDataType.get(entry.getKey())</span>
<span class="nc bnc" id="L454" title="All 2 branches missed.">                  .equals(ComponentFacet.TYPE_INTEGER)) {</span>
                // only values without shifting bits
<span class="nc bnc" id="L456" title="All 2 branches missed.">                if (term.bytes[term.offset] == LegacyNumericUtils.SHIFT_START_INT) {</span>
<span class="nc" id="L457">                  termValue = Integer</span>
<span class="nc" id="L458">                      .toString(LegacyNumericUtils.prefixCodedToInt(term));</span>
                } else {
                  continue;
                }
<span class="nc" id="L462">              } else if (facetDataType.get(entry.getKey())</span>
<span class="nc bnc" id="L463" title="All 2 branches missed.">                  .equals(ComponentFacet.TYPE_LONG)) {</span>
<span class="nc bnc" id="L464" title="All 2 branches missed.">                if (term.bytes[term.offset] == LegacyNumericUtils.SHIFT_START_LONG) {</span>
<span class="nc" id="L465">                  termValue = Long</span>
<span class="nc" id="L466">                      .toString(LegacyNumericUtils.prefixCodedToLong(term));</span>
                } else {
                  continue;
                }
              } else {
<span class="nc" id="L471">                termValue = term.utf8ToString();</span>
              }
<span class="nc bnc" id="L473" title="All 2 branches missed.">              if (!facetDataList.containsKey(termValue)) {</span>
<span class="nc" id="L474">                facetDataList.put(termValue,</span>
<span class="nc" id="L475">                    Arrays.copyOf(facetDataSublist, facetDataSublistCounter));</span>
              } else {
<span class="nc" id="L477">                int[] oldList = facetDataList.get(termValue);</span>
<span class="nc" id="L478">                int[] newList = new int[oldList.length</span>
                    + facetDataSublistCounter];
<span class="nc" id="L480">                System.arraycopy(oldList, 0, newList, 0, oldList.length);</span>
<span class="nc" id="L481">                System.arraycopy(facetDataSublist, 0, newList, oldList.length,</span>
                    facetDataSublistCounter);
<span class="nc" id="L483">                facetDataList.put(termValue, newList);</span>
              }
            }
<span class="nc" id="L486">          }</span>
        }
<span class="nc" id="L488">      }</span>
      
<span class="fc bfc" id="L490" title="All 2 branches covered.">      for (MtasSpanQuery sq : fieldInfo.spanQueryList) {</span>
        // what to collect
<span class="pc bpc" id="L492" title="1 of 2 branches missed.">        if (spansNumberData.containsKey(sq)) {</span>
<span class="fc" id="L493">          numberData = spansNumberData.get(sq);</span>
        } else {
<span class="nc" id="L495">          numberData = null;</span>
        }
<span class="fc bfc" id="L497" title="All 2 branches covered.">        if (spansMatchData.containsKey(sq)) {</span>
<span class="fc" id="L498">          matchData = spansMatchData.get(sq);</span>
        } else {
<span class="fc" id="L500">          matchData = null;</span>
        }
<span class="pc bpc" id="L502" title="3 of 4 branches missed.">        if ((numberData != null) || (matchData != null)) {</span>
<span class="fc" id="L503">          Spans spans = spansQueryWeight.get(sq).getSpans(lrc,</span>
              SpanWeight.Postings.POSITIONS);
<span class="pc bpc" id="L505" title="1 of 2 branches missed.">          if (spans != null) {</span>
            Iterator&lt;Integer&gt; it;
<span class="pc bpc" id="L507" title="1 of 2 branches missed.">            if (docSet != null) {</span>
<span class="fc" id="L508">              it = docSet.iterator();</span>
            } else {
<span class="nc" id="L510">              it = docList.iterator();</span>
            }
<span class="pc bpc" id="L512" title="1 of 2 branches missed.">            if (it.hasNext()) {</span>
<span class="fc" id="L513">              int docId = it.next();</span>
              int number;
              ArrayList&lt;Match&gt; matchDataList;
<span class="fc" id="L516">              Integer spansDocId = null;</span>
<span class="pc bpc" id="L517" title="1 of 2 branches missed.">              while (docId != DocIdSetIterator.NO_MORE_DOCS) {</span>
<span class="pc bpc" id="L518" title="1 of 2 branches missed.">                if (spans.advance(</span>
                    (docId - lrc.docBase)) == DocIdSetIterator.NO_MORE_DOCS) {
<span class="nc" id="L520">                  break;</span>
                }
<span class="fc" id="L522">                spansDocId = spans.docID() + lrc.docBase;</span>
<span class="pc bpc" id="L523" title="3 of 4 branches missed.">                while ((docId &lt; spansDocId) &amp;&amp; it.hasNext()) {</span>
<span class="nc" id="L524">                  docId = it.next();</span>
                }
<span class="pc bpc" id="L526" title="1 of 2 branches missed.">                if (docId &lt; spansDocId) {</span>
<span class="nc" id="L527">                  break;</span>
                }
<span class="pc bpc" id="L529" title="1 of 2 branches missed.">                if (spansDocId.equals(docId)) {</span>
<span class="fc" id="L530">                  number = 0;</span>
<span class="fc" id="L531">                  matchDataList = new ArrayList&lt;Match&gt;();</span>
                  int tmpStartPosition;
<span class="fc" id="L533">                  while ((tmpStartPosition = spans</span>
<span class="fc bfc" id="L534" title="All 2 branches covered.">                      .nextStartPosition()) != Spans.NO_MORE_POSITIONS) {</span>
<span class="fc" id="L535">                    number++;</span>
<span class="fc bfc" id="L536" title="All 2 branches covered.">                    if (matchData != null) {</span>
<span class="fc" id="L537">                      Match m = new Match(tmpStartPosition,</span>
<span class="fc" id="L538">                          spans.endPosition());</span>
<span class="fc" id="L539">                      matchDataList.add(m);</span>
<span class="fc" id="L540">                    }</span>
                  }
<span class="pc bpc" id="L542" title="1 of 2 branches missed.">                  if ((numberData != null)) {</span>
<span class="fc" id="L543">                    numberData.put(spansDocId, number);</span>
                  }
<span class="fc bfc" id="L545" title="All 2 branches covered.">                  if ((matchData != null)) {</span>
<span class="fc" id="L546">                    matchData.put(spansDocId, matchDataList);</span>
                  }
<span class="fc bfc" id="L548" title="All 2 branches covered.">                  if (it.hasNext()) {</span>
<span class="fc" id="L549">                    docId = it.next();</span>
                  } else {
                    break;
                  }
<span class="fc" id="L553">                }</span>
              }
            }
          }
        }
<span class="fc" id="L558">      }</span>
    }
    
    // collect position stats
<span class="fc bfc" id="L562" title="All 2 branches covered.">    if (needPositions) {</span>
<span class="pc bpc" id="L563" title="1 of 2 branches missed.">      if (mtasCodecInfo != null) {</span>
        // for relatively small numbers, compute only what is needed
<span class="fc bfc" id="L565" title="All 2 branches covered.">        if (docSet.size() &lt; Math.log(r.maxDoc())) {</span>
<span class="fc" id="L566">          positionsData = new HashMap&lt;Integer, Integer&gt;();</span>
<span class="fc bfc" id="L567" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="fc" id="L568">            positionsData.put(docId, mtasCodecInfo.getNumberOfPositions(field,</span>
                (docId - lrc.docBase)));
<span class="fc" id="L570">          }</span>
          // compute everything, only use what is needed
        } else {
<span class="fc" id="L573">          positionsData = mtasCodecInfo.getAllNumberOfPositions(field,</span>
              lrc.docBase);
<span class="fc bfc" id="L575" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="pc bpc" id="L576" title="1 of 2 branches missed.">            if (!positionsData.containsKey(docId)) {</span>
<span class="nc" id="L577">              positionsData.put(docId, 0);</span>
            }
<span class="fc" id="L579">          }</span>
        }
      } else {
<span class="nc" id="L582">        positionsData = new HashMap&lt;Integer, Integer&gt;();</span>
<span class="nc bnc" id="L583" title="All 2 branches missed.">        for (int docId : docSet) {</span>
<span class="nc" id="L584">          positionsData.put(docId, 0);</span>
<span class="nc" id="L585">        }</span>
      }
    }

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

<span class="fc bfc" id="L616" title="All 2 branches covered.">    if (fieldInfo.statsPositionList.size() &gt; 0) {</span>
      // create positions
<span class="fc" id="L618">      createPositions(fieldInfo.statsPositionList, positionsData, docSet);</span>
    }

<span class="fc bfc" id="L621" title="All 2 branches covered.">    if (fieldInfo.statsTokenList.size() &gt; 0) {</span>
      // create positions
<span class="fc" id="L623">      createTokens(fieldInfo.statsTokenList, tokensData, docSet);</span>
    }

<span class="pc bpc" id="L626" title="1 of 2 branches missed.">    if (fieldInfo.documentList.size() &gt; 0) {</span>
      // create document
<span class="nc" id="L628">      createDocument(fieldInfo.documentList, docList, field, lrc.docBase,</span>
          fieldInfo.uniqueKeyField, searcher, t, r, lrc);
    }
<span class="fc bfc" id="L631" title="All 2 branches covered.">    if (fieldInfo.spanQueryList.size() &gt; 0) {</span>
<span class="pc bpc" id="L632" title="1 of 2 branches missed.">      if (fieldInfo.statsSpanList.size() &gt; 0) {</span>
        // create stats
<span class="fc" id="L634">        createStats(fieldInfo.statsSpanList, positionsData, spansNumberData,</span>
<span class="fc" id="L635">            docSet.toArray(new Integer[docSet.size()]));</span>
      }
<span class="pc bpc" id="L637" title="1 of 2 branches missed.">      if (fieldInfo.listList.size() &gt; 0) {</span>
        // create list
<span class="nc" id="L639">        createList(fieldInfo.listList, spansNumberData, spansMatchData, docSet,</span>
            field, lrc.docBase, fieldInfo.uniqueKeyField, mtasCodecInfo,
            searcher);
      }
<span class="fc bfc" id="L643" title="All 2 branches covered.">      if (fieldInfo.groupList.size() &gt; 0) {</span>
        // create group
<span class="fc" id="L645">        createGroup(fieldInfo.groupList, spansMatchData, docSet,</span>
<span class="fc" id="L646">            fieldInfos.fieldInfo(field), field, lrc.docBase, mtasCodecInfo,</span>
            searcher, lrc);
      }
<span class="pc bpc" id="L649" title="1 of 2 branches missed.">      if (fieldInfo.kwicList.size() &gt; 0) {</span>
        // create kwic
<span class="nc" id="L651">        createKwic(fieldInfo.kwicList, spansMatchData, docList, field,</span>
            lrc.docBase, fieldInfo.uniqueKeyField, mtasCodecInfo, searcher);
      }
<span class="pc bpc" id="L654" title="1 of 2 branches missed.">      if (fieldInfo.facetList.size() &gt; 0) {</span>
        // create facets
<span class="nc" id="L656">        createFacet(fieldInfo.facetList, positionsData, spansNumberData,</span>
            facetData, docSet, field, lrc.docBase, fieldInfo.uniqueKeyField,
            mtasCodecInfo, searcher);
      }
    }
<span class="fc bfc" id="L661" title="All 2 branches covered.">    if (fieldInfo.termVectorList.size() &gt; 0) {</span>
<span class="fc" id="L662">      createTermvectorFull(fieldInfo.termVectorList, positionsData, docSet,</span>
          field, t, r, lrc);
<span class="fc" id="L664">      createTermvectorFirstRound(fieldInfo.termVectorList, positionsData,</span>
          docSet, field, t, r, lrc);
    }
<span class="fc" id="L667">  }</span>

  /**
   * Collect known prefixes.
   *
   * @param fi
   *          the fi
   * @return the hash set
   * @throws IOException
   *           Signals that an I/O exception has occurred.
   */
  private static HashSet&lt;String&gt; collectKnownPrefixes(FieldInfo fi)
      throws IOException {
<span class="pc bpc" id="L680" title="1 of 2 branches missed.">    if (fi != null) {</span>
<span class="fc" id="L681">      HashSet&lt;String&gt; result = new HashSet&lt;String&gt;();</span>
<span class="fc" id="L682">      String singlePositionPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SINGLE_POSITION);
<span class="fc" id="L684">      String multiplePositionPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_MULTIPLE_POSITION);
<span class="fc" id="L686">      String setPositionPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SET_POSITION);
<span class="pc bpc" id="L688" title="1 of 2 branches missed.">      if (singlePositionPrefixes != null) {</span>
<span class="fc" id="L689">        String[] prefixes = singlePositionPrefixes</span>
<span class="fc" id="L690">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L691" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L692">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L693" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L694">            result.add(item);</span>
          }
        }
      }
<span class="pc bpc" id="L698" title="1 of 2 branches missed.">      if (multiplePositionPrefixes != null) {</span>
<span class="fc" id="L699">        String[] prefixes = multiplePositionPrefixes</span>
<span class="fc" id="L700">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L701" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L702">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L703" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L704">            result.add(item);</span>
          }
        }
      }
<span class="pc bpc" id="L708" title="1 of 2 branches missed.">      if (setPositionPrefixes != null) {</span>
<span class="fc" id="L709">        String[] prefixes = setPositionPrefixes</span>
<span class="fc" id="L710">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L711" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L712">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L713" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L714">            result.add(item);</span>
          }
        }
      }
<span class="fc" id="L718">      return result;</span>
    } else {
<span class="nc" id="L720">      return null;</span>
    }
  }

  /**
   * Collect intersection prefixes.
   *
   * @param fi
   *          the fi
   * @return the hash set
   * @throws IOException
   *           Signals that an I/O exception has occurred.
   */
  private static HashSet&lt;String&gt; collectIntersectionPrefixes(FieldInfo fi)
      throws IOException {
<span class="pc bpc" id="L735" title="1 of 2 branches missed.">    if (fi != null) {</span>
<span class="fc" id="L736">      HashSet&lt;String&gt; result = new HashSet&lt;String&gt;();</span>
<span class="fc" id="L737">      String intersectingPrefixes = fi.getAttribute(</span>
          MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_INTERSECTION);
<span class="pc bpc" id="L739" title="1 of 2 branches missed.">      if (intersectingPrefixes != null) {</span>
<span class="fc" id="L740">        String[] prefixes = intersectingPrefixes</span>
<span class="fc" id="L741">            .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="fc bfc" id="L742" title="All 2 branches covered.">        for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="fc" id="L743">          String item = prefixes[i].trim();</span>
<span class="pc bpc" id="L744" title="1 of 2 branches missed.">          if (!item.equals(&quot;&quot;)) {</span>
<span class="fc" id="L745">            result.add(item);</span>
          }
        }
      }
<span class="fc" id="L749">      return result;</span>
    } else {
<span class="nc" id="L751">      return null;</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="pc bpc" id="L769" title="1 of 2 branches missed.">    if (fieldInfo.prefix != null) {</span>
<span class="nc" id="L770">      FieldInfo fi = fieldInfos.fieldInfo(field);</span>
<span class="nc bnc" id="L771" title="All 2 branches missed.">      if (fi != null) {</span>
<span class="nc" id="L772">        String singlePositionPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SINGLE_POSITION);
<span class="nc" id="L774">        String multiplePositionPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_MULTIPLE_POSITION);
<span class="nc" id="L776">        String setPositionPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_SET_POSITION);
<span class="nc" id="L778">        String intersectingPrefixes = fi.getAttribute(</span>
            MtasCodecPostingsFormat.MTAS_FIELDINFO_ATTRIBUTE_PREFIX_INTERSECTION);
<span class="nc bnc" id="L780" title="All 2 branches missed.">        if (singlePositionPrefixes != null) {</span>
<span class="nc" id="L781">          String[] prefixes = singlePositionPrefixes</span>
<span class="nc" id="L782">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="nc bnc" id="L783" title="All 2 branches missed.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="nc" id="L784">            fieldInfo.prefix.addSinglePosition(prefixes[i]);</span>
          }
        }
<span class="nc bnc" id="L787" title="All 2 branches missed.">        if (multiplePositionPrefixes != null) {</span>
<span class="nc" id="L788">          String[] prefixes = multiplePositionPrefixes</span>
<span class="nc" id="L789">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="nc bnc" id="L790" title="All 2 branches missed.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="nc" id="L791">            fieldInfo.prefix.addMultiplePosition(prefixes[i]);</span>
          }
        }
<span class="nc bnc" id="L794" title="All 2 branches missed.">        if (setPositionPrefixes != null) {</span>
<span class="nc" id="L795">          String[] prefixes = setPositionPrefixes</span>
<span class="nc" id="L796">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="nc bnc" id="L797" title="All 2 branches missed.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="nc" id="L798">            fieldInfo.prefix.addSetPosition(prefixes[i]);</span>
          }
        }
<span class="nc bnc" id="L801" title="All 2 branches missed.">        if (intersectingPrefixes != null) {</span>
<span class="nc" id="L802">          String[] prefixes = intersectingPrefixes</span>
<span class="nc" id="L803">              .split(Pattern.quote(MtasToken.DELIMITER));</span>
<span class="nc bnc" id="L804" title="All 2 branches missed.">          for (int i = 0; i &lt; prefixes.length; i++) {</span>
<span class="nc" id="L805">            fieldInfo.prefix.addIntersecting(prefixes[i]);</span>
          }
        }
      }
    }
<span class="fc" id="L810">  }</span>

  /**
   * Collect spans for occurences.
   *
   * @param occurences
   *          the occurences
   * @param prefixes
   *          the prefixes
   * @param field
   *          the field
   * @param mtasCodecInfo
   *          the mtas codec info
   * @param searcher
   *          the searcher
   * @param lrc
   *          the lrc
   * @return the hash map
   * @throws IOException
   *           Signals that an I/O exception has occurred.
   */
  private static HashMap&lt;GroupHit, Spans&gt; collectSpansForOccurences(
      HashSet&lt;GroupHit&gt; occurences, HashSet&lt;String&gt; prefixes, String field,
      CodecInfo mtasCodecInfo, IndexSearcher searcher, LeafReaderContext lrc)
      throws IOException {
<span class="nc" id="L835">    HashMap&lt;GroupHit, Spans&gt; list = new HashMap&lt;GroupHit, Spans&gt;();</span>
<span class="nc" id="L836">    IndexReader reader = searcher.getIndexReader();</span>
<span class="nc bnc" id="L837" title="All 2 branches missed.">    for (GroupHit hit : occurences) {</span>
<span class="nc" id="L838">      MtasSpanQuery queryHit = createQueryFromGroupHit(prefixes, field, hit);</span>
<span class="nc bnc" id="L839" title="All 2 branches missed.">      if (queryHit != null) {</span>
<span class="nc" id="L840">        MtasSpanQuery queryHitRewritten = queryHit.rewrite(reader);</span>
<span class="nc" id="L841">        SpanWeight weight = (SpanWeight) queryHitRewritten</span>
<span class="nc" id="L842">            .createWeight(searcher, false);</span>
<span class="nc" id="L843">        Spans spans = weight.getSpans(lrc, SpanWeight.Postings.POSITIONS);</span>
<span class="nc bnc" id="L844" title="All 2 branches missed.">        if (spans != null) {</span>
<span class="nc" id="L845">          list.put(hit, spans);</span>
        }
      }
<span class="nc" id="L848">    }</span>
<span class="nc" id="L849">    return list;</span>
  }

  /**
   * Creates the query from group hit.
   *
   * @param prefixes
   *          the prefixes
   * @param field
   *          the field
   * @param hit
   *          the hit
   * @return the span query
   */
  private static MtasSpanQuery createQueryFromGroupHit(HashSet&lt;String&gt; prefixes,
      String field, GroupHit hit) {
    // initial check
<span class="nc bnc" id="L866" title="All 6 branches missed.">    if (prefixes == null || field == null || hit == null) {</span>
<span class="nc" id="L867">      return null;</span>
    } else {
<span class="nc" id="L869">      MtasSpanQuery query = null;</span>
<span class="nc" id="L870">      MtasSpanQuery hitQuery = null;</span>
      // check for missing
<span class="nc bnc" id="L872" title="All 4 branches missed.">      if (hit.missingLeft != null &amp;&amp; hit.missingLeft.length &gt; 0) {</span>
<span class="nc bnc" id="L873" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.missingLeft.length; i++) {</span>
<span class="nc bnc" id="L874" title="All 2 branches missed.">          if (hit.missingLeft[i].size() != hit.unknownLeft[i].size()) {</span>
<span class="nc" id="L875">            return null;</span>
          }
        }
      }
<span class="nc bnc" id="L879" title="All 4 branches missed.">      if (hit.missingHit != null &amp;&amp; hit.missingHit.length &gt; 0) {</span>
<span class="nc bnc" id="L880" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.missingHit.length; i++) {</span>
<span class="nc bnc" id="L881" title="All 2 branches missed.">          if (hit.missingHit[i].size() != hit.unknownHit[i].size()) {</span>
<span class="nc" id="L882">            return null;</span>
          }
        }
      }
<span class="nc bnc" id="L886" title="All 4 branches missed.">      if (hit.missingRight != null &amp;&amp; hit.missingRight.length &gt; 0) {</span>
<span class="nc bnc" id="L887" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.missingRight.length; i++) {</span>
<span class="nc bnc" id="L888" title="All 2 branches missed.">          if (hit.missingRight[i].size() != hit.unknownRight[i].size()) {</span>
<span class="nc" id="L889">            return null;</span>
          }
        }
      }

<span class="nc bnc" id="L894" title="All 4 branches missed.">      if (hit.dataHit != null &amp;&amp; hit.dataHit.length &gt; 0) {</span>
<span class="nc" id="L895">        List&lt;MtasSpanSequenceItem&gt; items = new ArrayList&lt;MtasSpanSequenceItem&gt;();</span>
<span class="nc bnc" id="L896" title="All 2 branches missed.">        for (int i = 0; i &lt; hit.dataHit.length; i++) {</span>
<span class="nc" id="L897">          MtasSpanQuery item = null;</span>
<span class="nc bnc" id="L898" title="All 2 branches missed.">          if (hit.dataHit[i].size() == 0) {</span>
<span class="nc" id="L899">            item = new MtasSpanMatchAllQuery(field);</span>
<span class="nc bnc" id="L900" title="All 2 branches missed.">          } else if (hit.dataHit[i].size() == 1) {</span>
<span class="nc" id="L901">            Term term = new Term(field, hit.dataHit[i].get(0));</span>
<span class="nc" id="L902">            item = new MtasSpanTermQuery(term);</span>
<span class="nc" id="L903">          } else {</span>
<span class="nc" id="L904">            MtasSpanQuery[] subList = new MtasSpanQuery[hit.dataHit[i].size()];</span>
<span class="nc bnc" id="L905" title="All 2 branches missed.">            for (int j = 0; j &lt; hit.dataHit[i].size(); j++) {</span>
<span class="nc" id="L906">              Term term = new Term(field, hit.dataHit[i].get(j));</span>
<span class="nc" id="L907">              subList[j] = new MtasSpanTermQuery(term);</span>
            }
<span class="nc" id="L909">            item = new MtasSpanAndQuery(subList);</span>
          }
<span class="nc" id="L911">          items.add(new MtasSpanSequenceItem(item, false));</span>
        }
<span class="nc" id="L913">        hitQuery = new MtasSpanSequenceQuery(items, null, null);</span>
      }
<span class="nc bnc" id="L915" title="All 2 branches missed.">      if (hitQuery != null) {</span>
<span class="nc" id="L916">        query = hitQuery;</span>
      }
<span class="nc" id="L918">      return query;</span>
    }
  }

  /**
   * Compute positions.
   *
   * @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
   * @return the hash map
   * @throws IOException
   *           Signals that an I/O exception has occurred.
   */
  private static HashMap&lt;Integer, Integer&gt; computePositions(
      CodecInfo mtasCodecInfo, LeafReader r, LeafReaderContext lrc,
      String field, Terms t, List&lt;Integer&gt; docSet) throws IOException {
    HashMap&lt;Integer, Integer&gt; positionsData;
<span class="nc bnc" id="L945" title="All 2 branches missed.">    if (mtasCodecInfo != null) {</span>
      // for relatively small numbers, compute only what is needed
<span class="nc bnc" id="L947" title="All 2 branches missed.">      if (docSet.size() &lt; Math.log(r.maxDoc())) {</span>
<span class="nc" id="L948">        positionsData = new HashMap&lt;Integer, Integer&gt;();</span>
<span class="nc bnc" id="L949" title="All 2 branches missed.">        for (int docId : docSet) {</span>
<span class="nc" id="L950">          positionsData.put(docId,</span>
<span class="nc" id="L951">              mtasCodecInfo.getNumberOfPositions(field, (docId - lrc.docBase)));</span>
<span class="nc" id="L952">        }</span>
        // compute everything, only use what is needed
      } else {
<span class="nc" id="L955">        positionsData = mtasCodecInfo.getAllNumberOfPositions(field,</span>
            lrc.docBase);
<span class="nc bnc" id="L957" title="All 2 branches missed.">        for (int docId : docSet) {</span>
<span class="nc bnc" id="L958" title="All 2 branches missed.">          if (!positionsData.containsKey(docId)) {</span>
<span class="nc" id="L959">            positionsData.put(docId, 0);</span>
          }
<span class="nc" id="L961">        }</span>
      }
    } else {
<span class="nc" id="L964">      positionsData = new HashMap&lt;Integer, Integer&gt;();</span>
<span class="nc bnc" id="L965" title="All 2 branches missed.">      for (int docId : docSet) {</span>
<span class="nc" id="L966">        positionsData.put(docId, 0);</span>
<span class="nc" id="L967">      }</span>
    }
<span class="nc" id="L969">    return positionsData;</span>
  }

  /**
   * Compute arguments.
   *
   * @param spansNumberData
   *          the spans number data
   * @param queries
   *          the queries
   * @param docSet
   *          the doc set
   * @return the hash map
   */
  private static HashMap&lt;Integer, long[]&gt; computeArguments(
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, Integer&gt;&gt; spansNumberData,
      MtasSpanQuery[] queries, Integer[] docSet) {
<span class="fc" id="L986">    HashMap&lt;Integer, long[]&gt; args = new HashMap&lt;Integer, long[]&gt;();</span>
<span class="fc bfc" id="L987" title="All 2 branches covered.">    for (int q = 0; q &lt; queries.length; q++) {</span>
<span class="fc" id="L988">      HashMap&lt;Integer, Integer&gt; tmpData = spansNumberData.get(queries[q]);</span>
<span class="fc" id="L989">      long[] tmpList = null;</span>
<span class="fc bfc" id="L990" title="All 2 branches covered.">      for (int docId : docSet) {</span>
<span class="pc bpc" id="L991" title="2 of 4 branches missed.">        if (tmpData != null &amp;&amp; tmpData.containsKey(docId)) {</span>
<span class="fc bfc" id="L992" title="All 2 branches covered.">          if (!args.containsKey(docId)) {</span>
<span class="fc" id="L993">            tmpList = new long[queries.length];</span>
          } else {
<span class="fc" id="L995">            tmpList = args.get(docId);</span>
          }
<span class="fc" id="L997">          tmpList[q] = tmpData.get(docId);</span>
<span class="fc" id="L998">          args.put(docId, tmpList);</span>
<span class="nc bnc" id="L999" title="All 2 branches missed.">        } else if (!args.containsKey(docId)) {</span>
<span class="nc" id="L1000">          tmpList = new long[queries.length];</span>
<span class="nc" id="L1001">          args.put(docId, tmpList);</span>
        }
      }
    }
<span class="fc" id="L1005">    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="L1019" title="All 2 branches missed.">    if (facetDocList != null) {</span>
<span class="nc bnc" id="L1020" title="All 2 branches missed.">      if (docSet != null) {</span>
<span class="nc" id="L1021">        Integer[] c = new Integer[Math.min(facetDocList.length, docSet.length)];</span>
<span class="nc" id="L1022">        int ai = 0, bi = 0, ci = 0;</span>
<span class="nc bnc" id="L1023" title="All 4 branches missed.">        while (ai &lt; facetDocList.length &amp;&amp; bi &lt; docSet.length) {</span>
<span class="nc bnc" id="L1024" title="All 2 branches missed.">          if (facetDocList[ai] &lt; docSet[bi]) {</span>
<span class="nc" id="L1025">            ai++;</span>
<span class="nc bnc" id="L1026" title="All 2 branches missed.">          } else if (facetDocList[ai] &gt; docSet[bi]) {</span>
<span class="nc" id="L1027">            bi++;</span>
          } else {
<span class="nc bnc" id="L1029" title="All 4 branches missed.">            if (ci == 0 || facetDocList[ai] != c[ci - 1]) {</span>
<span class="nc" id="L1030">              c[ci++] = facetDocList[ai];</span>
            }
<span class="nc" id="L1032">            ai++;</span>
<span class="nc" id="L1033">            bi++;</span>
          }
        }
<span class="nc" id="L1036">        return Arrays.copyOfRange(c, 0, ci);</span>
      }
    }
<span class="nc" id="L1039">    return null;</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,
      HashMap&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet)
      throws IOException {
<span class="pc bpc" id="L1057" title="1 of 2 branches missed.">    if (statsPositionList != null) {</span>
<span class="fc bfc" id="L1058" title="All 2 branches covered.">      for (ComponentPosition position : statsPositionList) {</span>
<span class="fc" id="L1059">        position.dataCollector.initNewList(1);</span>
        Integer tmpValue;
<span class="fc" id="L1061">        long[] values = new long[docSet.size()];</span>
<span class="fc" id="L1062">        int value, number = 0;</span>
<span class="fc bfc" id="L1063" title="All 2 branches covered.">        for (int docId : docSet) {</span>
<span class="fc" id="L1064">          tmpValue = positionsData.get(docId);</span>
<span class="pc bpc" id="L1065" title="1 of 2 branches missed.">          value = tmpValue == null ? 0 : tmpValue.intValue();</span>
<span class="fc bfc" id="L1066" title="All 2 branches covered.">          if (((position.minimumLong == null)</span>
<span class="fc bfc" id="L1067" title="All 4 branches covered.">              || (value &gt;= position.minimumLong))</span>
              &amp;&amp; ((position.maximumLong == null)
<span class="fc bfc" id="L1069" title="All 2 branches covered.">                  || (value &lt;= position.maximumLong))) {</span>
<span class="fc" id="L1070">            values[number] = value;</span>
<span class="fc" id="L1071">            number++;</span>
          }
<span class="fc" id="L1073">        }</span>
<span class="fc bfc" id="L1074" title="All 2 branches covered.">        if (number &gt; 0) {</span>
<span class="fc" id="L1075">          position.dataCollector.add(values, number);</span>
        }
<span class="fc" id="L1077">        position.dataCollector.closeNewList();</span>
<span class="fc" id="L1078">      }</span>
    }
<span class="fc" id="L1080">  }</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,
      HashMap&lt;Integer, Integer&gt; tokensData, List&lt;Integer&gt; docSet)
      throws IOException {
<span class="pc bpc" id="L1097" title="1 of 2 branches missed.">    if (statsTokenList != null) {</span>
<span class="fc bfc" id="L1098" title="All 2 branches covered.">      for (ComponentToken token : statsTokenList) {</span>
<span class="fc" id="L1099">        token.dataCollector.initNewList(1);</span>
        Integer tmpValue;
<span class="fc" id="L1101">        long[] values = new long[docSet.size()];</span>
<span class="fc" id="L1102">        int value, number = 0;</span>
<span class="pc bpc" id="L1103" title="1 of 2 branches missed.">        if (tokensData != null) {</span>
<span class="fc bfc" id="L1104" title="All 2 branches covered.">          for (int docId : docSet) {</span>
<span class="fc" id="L1105">            tmpValue = tokensData.get(docId);</span>
<span class="pc bpc" id="L1106" title="1 of 2 branches missed.">            value = tmpValue == null ? 0 : tmpValue.intValue();</span>
<span class="pc bpc" id="L1107" title="4 of 6 branches missed.">            if (((token.minimumLong == null) || (value &gt;= token.minimumLong))</span>
                &amp;&amp; ((token.maximumLong == null)
<span class="nc bnc" id="L1109" title="All 2 branches missed.">                    || (value &lt;= token.maximumLong))) {</span>
<span class="fc" id="L1110">              values[number] = value;</span>
<span class="fc" id="L1111">              number++;</span>
            }
<span class="fc" id="L1113">          }</span>
        }
<span class="fc bfc" id="L1115" title="All 2 branches covered.">        if (number &gt; 0) {</span>
<span class="fc" id="L1116">          token.dataCollector.add(values, number);</span>
        }
<span class="fc" id="L1118">        token.dataCollector.closeNewList();</span>
<span class="fc" id="L1119">      }</span>
    }
<span class="fc" id="L1121">  }</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,
      HashMap&lt;Integer, Integer&gt; positionsData,
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, Integer&gt;&gt; spansNumberData,
      Integer[] docSet) throws IOException {
<span class="pc bpc" id="L1141" title="1 of 2 branches missed.">    if (statsSpanList != null) {</span>
<span class="fc bfc" id="L1142" title="All 2 branches covered.">      for (ComponentSpan span : statsSpanList) {</span>
<span class="pc bpc" id="L1143" title="1 of 2 branches missed.">        if (span.parser.needArgumentsNumber() &gt; span.queries.length) {</span>
<span class="nc" id="L1144">          throw new IOException(</span>
              &quot;function &quot; + span.parser + &quot; expects (at least) &quot;
<span class="nc" id="L1146">                  + span.parser.needArgumentsNumber() + &quot; queries&quot;);</span>
        }
        // collect
<span class="fc" id="L1149">        HashMap&lt;Integer, long[]&gt; args = computeArguments(spansNumberData,</span>
            span.queries, docSet);
<span class="pc bpc" id="L1151" 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="L1153" 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="L1156" title="2 of 4 branches missed.">                  || (span.functionBasic() &amp;&amp; span.functionSumRule()</span>
<span class="pc bpc" id="L1157" title="1 of 2 branches missed.">                      &amp;&amp; !span.functionNeedPositions()))) {</span>
            // initialise
<span class="fc" id="L1159">            int length = span.parser.needArgumentsNumber();</span>
<span class="fc" id="L1160">            long[] valueSum = new long[length];</span>
<span class="fc" id="L1161">            long valuePositions = 0;</span>
            // collect
<span class="pc bpc" id="L1163" title="1 of 2 branches missed.">            if (docSet.length &gt; 0) {</span>
              long[] tmpArgs;
<span class="fc bfc" id="L1165" title="All 2 branches covered.">              for (int docId : docSet) {</span>
<span class="fc" id="L1166">                tmpArgs = args.get(docId);</span>
<span class="fc bfc" id="L1167" title="All 2 branches covered.">                valuePositions += (positionsData == null) ? 0</span>
<span class="fc" id="L1168">                    : positionsData.get(docId);</span>
<span class="pc bpc" id="L1169" title="1 of 2 branches missed.">                if (tmpArgs != null) {</span>
<span class="fc bfc" id="L1170" title="All 2 branches covered.">                  for (int i = 0; i &lt; length; i++) {</span>
<span class="fc" id="L1171">                    valueSum[i] += tmpArgs[i];</span>
                  }
                }
              }
              long valueLong;
<span class="fc" id="L1176">              span.dataCollector.initNewList(1);</span>
              try {
<span class="fc" id="L1178">                valueLong = span.parser.getValueLong(valueSum, valuePositions);</span>
<span class="fc" id="L1179">                span.dataCollector.add(valueLong, docSet.length);</span>
<span class="nc" id="L1180">              } catch (IOException e) {</span>
<span class="nc" id="L1181">                span.dataCollector.error(e.getMessage());</span>
<span class="fc" id="L1182">              }</span>
<span class="pc bpc" id="L1183" title="1 of 2 branches missed.">              if (span.functions != null) {</span>
<span class="fc bfc" id="L1184" title="All 2 branches covered.">                for (SubComponentFunction function : span.functions) {</span>
<span class="fc" id="L1185">                  function.dataCollector.initNewList(1);</span>
<span class="pc bpc" id="L1186" title="1 of 2 branches missed.">                  if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                    try {
<span class="fc" id="L1188">                      valueLong = function.parserFunction.getValueLong(valueSum,</span>
                          valuePositions);
<span class="fc" id="L1190">                      function.dataCollector.add(valueLong, docSet.length);</span>
<span class="nc" id="L1191">                    } catch (IOException e) {</span>
<span class="nc" id="L1192">                      function.dataCollector.error(e.getMessage());</span>
<span class="pc" id="L1193">                    }</span>
<span class="nc" id="L1194">                  } else if (function.dataType</span>
<span class="nc bnc" id="L1195" title="All 2 branches missed.">                      .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
                    try {
<span class="nc" id="L1197">                      double valueDouble = function.parserFunction</span>
<span class="nc" id="L1198">                          .getValueDouble(valueSum, valuePositions);</span>
<span class="nc" id="L1199">                      function.dataCollector.add(valueDouble, docSet.length);</span>
<span class="nc" id="L1200">                    } catch (IOException e) {</span>
<span class="nc" id="L1201">                      function.dataCollector.error(e.getMessage());</span>
<span class="nc" id="L1202">                    }</span>
                  } else {
<span class="nc" id="L1204">                    throw new IOException(</span>
                        &quot;can't handle function dataType &quot; + function.dataType);
                  }
<span class="fc" id="L1207">                  function.dataCollector.closeNewList();</span>
<span class="fc" id="L1208">                }</span>
              }
<span class="fc" id="L1210">              span.dataCollector.closeNewList();</span>
            }
<span class="fc" id="L1212">          } else {</span>
            // collect
<span class="pc bpc" id="L1214" title="1 of 2 branches missed.">            if (docSet.length &gt; 0) {</span>
<span class="fc" id="L1215">              int number = 0, positions;</span>
              long valueLong;
              double valueDouble;
<span class="fc" id="L1218">              long values[] = new long[docSet.length];</span>
<span class="fc" id="L1219">              long functionValuesLong[][] = null;</span>
<span class="fc" id="L1220">              double functionValuesDouble[][] = null;</span>
<span class="fc" id="L1221">              span.dataCollector.initNewList(1);</span>
<span class="pc bpc" id="L1222" title="1 of 2 branches missed.">              if (span.functions != null) {</span>
<span class="fc" id="L1223">                functionValuesLong = new long[span.functions.size()][];</span>
<span class="fc" id="L1224">                functionValuesDouble = new double[span.functions.size()][];</span>
<span class="pc bpc" id="L1225" title="1 of 2 branches missed.">                for (int i = 0; i &lt; span.functions.size(); i++) {</span>
<span class="nc" id="L1226">                  SubComponentFunction function = span.functions.get(i);</span>
<span class="nc bnc" id="L1227" title="All 2 branches missed.">                  if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L1228">                    functionValuesLong[i] = new long[docSet.length];</span>
<span class="nc" id="L1229">                    functionValuesDouble[i] = null;</span>
<span class="nc" id="L1230">                  } else if (function.dataType</span>
<span class="nc bnc" id="L1231" title="All 2 branches missed.">                      .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L1232">                    functionValuesLong[i] = null;</span>
<span class="nc" id="L1233">                    functionValuesDouble[i] = new double[docSet.length];</span>
                  }
<span class="nc" id="L1235">                  function.dataCollector.initNewList(1);</span>
                }
              }
<span class="fc bfc" id="L1238" title="All 2 branches covered.">              for (int docId : docSet) {</span>
<span class="pc bpc" id="L1239" title="1 of 2 branches missed.">                positions = (positionsData == null) ? 0</span>
<span class="nc bnc" id="L1240" title="All 2 branches missed.">                    : (positionsData.get(docId) == null ? 0</span>
<span class="pc" id="L1241">                        : positionsData.get(docId));</span>
                try {
<span class="fc" id="L1243">                  valueLong = span.parser.getValueLong(args.get(docId),</span>
                      positions);
<span class="fc bfc" id="L1245" title="All 2 branches covered.">                  if (((span.minimumLong == null)</span>
<span class="fc bfc" id="L1246" title="All 4 branches covered.">                      || (valueLong &gt;= span.minimumLong))</span>
                      &amp;&amp; ((span.maximumLong == null)
<span class="fc bfc" id="L1248" title="All 2 branches covered.">                          || (valueLong &lt;= span.maximumLong))) {</span>
<span class="fc" id="L1249">                    values[number] = valueLong;</span>
<span class="pc bpc" id="L1250" title="1 of 2 branches missed.">                    if (span.functions != null) {</span>
<span class="pc bpc" id="L1251" title="1 of 2 branches missed.">                      for (int i = 0; i &lt; span.functions.size(); i++) {</span>
<span class="nc" id="L1252">                        SubComponentFunction function = span.functions.get(i);</span>
                        try {
<span class="nc" id="L1254">                          if (function.dataType</span>
<span class="nc bnc" id="L1255" title="All 2 branches missed.">                              .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L1256">                            valueLong = function.parserFunction</span>
<span class="nc" id="L1257">                                .getValueLong(args.get(docId), positions);</span>
<span class="nc" id="L1258">                            functionValuesLong[i][number] = valueLong;</span>
<span class="nc" id="L1259">                          } else if (function.dataType</span>
<span class="nc bnc" id="L1260" title="All 2 branches missed.">                              .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L1261">                            valueDouble = function.parserFunction</span>
<span class="nc" id="L1262">                                .getValueDouble(args.get(docId), positions);</span>
<span class="nc" id="L1263">                            functionValuesDouble[i][number] = valueDouble;</span>
                          }
<span class="nc" id="L1265">                        } catch (IOException e) {</span>
<span class="nc" id="L1266">                          function.dataCollector.error(e.getMessage());</span>
<span class="nc" id="L1267">                        }</span>
                      }
                    }
<span class="fc" id="L1270">                    number++;</span>
                  }
<span class="nc" id="L1272">                } catch (IOException e) {</span>
<span class="nc" id="L1273">                  span.dataCollector.error(e.getMessage());</span>
<span class="fc" id="L1274">                }</span>
              }
<span class="fc bfc" id="L1276" title="All 2 branches covered.">              if (number &gt; 0) {</span>
<span class="fc" id="L1277">                span.dataCollector.add(values, number);</span>
<span class="pc bpc" id="L1278" title="1 of 2 branches missed.">                if (span.functions != null) {</span>
<span class="pc bpc" id="L1279" title="1 of 2 branches missed.">                  for (int i = 0; i &lt; span.functions.size(); i++) {</span>
<span class="nc" id="L1280">                    SubComponentFunction function = span.functions.get(i);</span>
<span class="nc bnc" id="L1281" title="All 2 branches missed.">                    if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L1282">                      function.dataCollector.add(functionValuesLong[i], number);</span>
<span class="nc" id="L1283">                    } else if (function.dataType</span>
<span class="nc bnc" id="L1284" title="All 2 branches missed.">                        .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L1285">                      function.dataCollector.add(functionValuesDouble[i],</span>
                          number);
                    }
                  }
                }
              }
<span class="fc" id="L1291">              span.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L1292" title="1 of 2 branches missed.">              if (span.functions != null) {</span>
<span class="pc bpc" id="L1293" title="1 of 2 branches missed.">                for (SubComponentFunction function : span.functions) {</span>
<span class="nc" id="L1294">                  function.dataCollector.closeNewList();</span>
<span class="nc" id="L1295">                }</span>
              }
<span class="fc" id="L1297">            }</span>
          }
        } else {
<span class="nc" id="L1300">          throw new IOException(&quot;unexpected dataType &quot; + span.dataType);</span>
        }
<span class="fc" id="L1302">      }</span>
    }
<span class="fc" id="L1304">  }</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,
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, Integer&gt;&gt; spansNumberData,
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, ArrayList&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="L1335" title="All 2 branches missed.">    if (listList != null) {</span>
<span class="nc bnc" id="L1336" title="All 2 branches missed.">      for (ComponentList list : listList) {</span>
        // collect not only stats
<span class="nc bnc" id="L1338" title="All 2 branches missed.">        if (list.number &gt; 0) {</span>
<span class="nc" id="L1339">          HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt; matchData = spansMatchData</span>
<span class="nc" id="L1340">              .get(list.spanQuery);</span>
<span class="nc" id="L1341">          HashMap&lt;Integer, Integer&gt; numberData = spansNumberData</span>
<span class="nc" id="L1342">              .get(list.spanQuery);</span>
          ArrayList&lt;Match&gt; matchList;
          Integer matchNumber;
<span class="nc bnc" id="L1345" title="All 2 branches missed.">          if (list.output.equals(ComponentList.LIST_OUTPUT_HIT)) {</span>
<span class="nc bnc" id="L1346" title="All 2 branches missed.">            for (int docId : docSet) {</span>
<span class="nc bnc" id="L1347" title="All 2 branches missed.">              if (matchData != null</span>
<span class="nc bnc" id="L1348" title="All 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
<span class="nc bnc" id="L1349" title="All 2 branches missed.">                if (list.position &lt; (list.start + list.number)) {</span>
<span class="nc" id="L1350">                  boolean getDoc = false;</span>
                  Match m;
<span class="nc bnc" id="L1352" title="All 2 branches missed.">                  for (int i = 0; i &lt; matchList.size(); i++) {</span>
<span class="nc bnc" id="L1353" 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="L1355">                      m = matchList.get(i);</span>
<span class="nc" id="L1356">                      getDoc = true;</span>
<span class="nc" id="L1357">                      int startPosition = m.startPosition;</span>
<span class="nc" id="L1358">                      int endPosition = m.endPosition - 1;</span>
<span class="nc" id="L1359">                      ArrayList&lt;MtasTreeHit&lt;String&gt;&gt; terms = mtasCodecInfo</span>
<span class="nc" id="L1360">                          .getPositionedTermsByPrefixesAndPositionRange(field,</span>
                              (docId - docBase), list.prefixes,
                              startPosition - list.left,
                              endPosition + list.right);
                      // construct hit
<span class="nc" id="L1365">                      HashMap&lt;Integer, ArrayList&lt;String&gt;&gt; kwicListHits = new HashMap&lt;Integer, ArrayList&lt;String&gt;&gt;();</span>
<span class="nc" id="L1366">                      for (int position = Math.max(0,</span>
<span class="nc bnc" id="L1367" title="All 2 branches missed.">                          startPosition - list.left); position &lt;= (endPosition</span>
<span class="nc" id="L1368">                              + list.right); position++) {</span>
<span class="nc" id="L1369">                        kwicListHits.put(position, new ArrayList&lt;String&gt;());</span>
                      }
                      ArrayList&lt;String&gt; termList;
<span class="nc bnc" id="L1372" title="All 2 branches missed.">                      for (MtasTreeHit&lt;String&gt; term : terms) {</span>
<span class="nc" id="L1373">                        for (int position = Math.max(</span>
                            (startPosition - list.left),
<span class="nc bnc" id="L1375" title="All 2 branches missed.">                            term.startPosition); position &lt;= Math.min(</span>
                                (endPosition + list.right),
<span class="nc" id="L1377">                                term.endPosition); position++) {</span>
<span class="nc" id="L1378">                          termList = kwicListHits.get(position);</span>
<span class="nc" id="L1379">                          termList.add(term.data);</span>
                        }
<span class="nc" id="L1381">                      }</span>
<span class="nc" id="L1382">                      list.hits.add(new ListHit(docId, i, m, kwicListHits));</span>
                    }
<span class="nc" id="L1384">                    list.position++;</span>
                  }
<span class="nc bnc" id="L1386" title="All 2 branches missed.">                  if (getDoc) {</span>
                    // get unique id
<span class="nc" id="L1388">                    Document doc = searcher.doc(docId,</span>
<span class="nc" id="L1389">                        new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L1390">                    IndexableField indxfld = doc.getField(uniqueKeyField);</span>
                    // get other doc info
<span class="nc bnc" id="L1392" title="All 2 branches missed.">                    if (indxfld != null) {</span>
<span class="nc" id="L1393">                      list.uniqueKey.put(docId, indxfld.stringValue());</span>
                    }
<span class="nc" id="L1395">                    list.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L1396">                    IndexDoc mDoc = mtasCodecInfo.getDoc(field,</span>
                        (docId - docBase));
<span class="nc bnc" id="L1398" title="All 2 branches missed.">                    if (mDoc != null) {</span>
<span class="nc" id="L1399">                      list.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L1400">                      list.maxPosition.put(docId, mDoc.maxPosition);</span>
                    }
                  }
<span class="nc" id="L1403">                } else {</span>
<span class="nc" id="L1404">                  list.position += matchList.size();</span>
                }
<span class="nc bnc" id="L1406" title="All 2 branches missed.">              } else if (numberData != null</span>
<span class="nc bnc" id="L1407" title="All 2 branches missed.">                  &amp;&amp; (matchNumber = numberData.get(docId)) != null) {</span>
<span class="nc" id="L1408">                list.position += matchNumber;                </span>
              }
<span class="nc" id="L1410">            }</span>
<span class="nc" id="L1411">            list.total = list.position;</span>
<span class="nc bnc" id="L1412" title="All 2 branches missed.">          } else if (list.output.equals(ComponentList.LIST_OUTPUT_TOKEN)) {</span>
<span class="nc bnc" id="L1413" title="All 2 branches missed.">            for (int docId : docSet) {</span>
<span class="nc bnc" id="L1414" title="All 2 branches missed.">              if (matchData != null</span>
<span class="nc bnc" id="L1415" title="All 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
<span class="nc bnc" id="L1416" title="All 2 branches missed.">                if (list.position &lt; (list.start + list.number)) {</span>
<span class="nc" id="L1417">                  boolean getDoc = false;</span>
                  Match m;
<span class="nc bnc" id="L1419" title="All 2 branches missed.">                  for (int i = 0; i &lt; matchList.size(); i++) {</span>
<span class="nc bnc" id="L1420" 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="L1422">                      m = matchList.get(i);</span>
<span class="nc" id="L1423">                      getDoc = true;</span>
<span class="nc" id="L1424">                      int startPosition = m.startPosition;</span>
<span class="nc" id="L1425">                      int endPosition = m.endPosition - 1;</span>
                      ArrayList&lt;MtasTokenString&gt; tokens;
<span class="nc" id="L1427">                      tokens = mtasCodecInfo</span>
<span class="nc" id="L1428">                          .getPrefixFilteredObjectsByPositions(field,</span>
                              (docId - docBase), list.prefixes,
                              startPosition - list.left,
                              endPosition + list.right);
<span class="nc" id="L1432">                      list.tokens.add(new ListToken(docId, i, m, tokens));</span>
                    }
<span class="nc" id="L1434">                    list.position++;</span>
                  }
<span class="nc bnc" id="L1436" title="All 2 branches missed.">                  if (getDoc) {</span>
                    // get unique id
<span class="nc" id="L1438">                    Document doc = searcher.doc(docId,</span>
<span class="nc" id="L1439">                        new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L1440">                    IndexableField indxfld = doc.getField(uniqueKeyField);</span>
                    // get other doc info
<span class="nc bnc" id="L1442" title="All 2 branches missed.">                    if (indxfld != null) {</span>
<span class="nc" id="L1443">                      list.uniqueKey.put(docId, indxfld.stringValue());</span>
                    }
<span class="nc" id="L1445">                    list.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L1446">                    IndexDoc mDoc = mtasCodecInfo.getDoc(field,</span>
                        (docId - docBase));
<span class="nc bnc" id="L1448" title="All 2 branches missed.">                    if (mDoc != null) {</span>
<span class="nc" id="L1449">                      list.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L1450">                      list.maxPosition.put(docId, mDoc.maxPosition);</span>
                    }
                  }
<span class="nc" id="L1453">                } else {</span>
<span class="nc" id="L1454">                  list.position += matchList.size();</span>
                }
<span class="nc bnc" id="L1456" title="All 2 branches missed.">              } else if (numberData != null</span>
<span class="nc bnc" id="L1457" title="All 2 branches missed.">                  &amp;&amp; (matchNumber = numberData.get(docId)) != null) {</span>
<span class="nc" id="L1458">                list.position += matchNumber;                </span>
              }
<span class="nc" id="L1460">            }</span>
<span class="nc" id="L1461">            list.total = list.position;</span>
          }

<span class="nc" id="L1464">        } else {</span>
<span class="nc" id="L1465">          HashMap&lt;Integer, Integer&gt; data = spansNumberData.get(list.spanQuery);</span>
<span class="nc bnc" id="L1466" title="All 2 branches missed.">          if (data != null) {</span>
<span class="nc bnc" id="L1467" title="All 2 branches missed.">            for (int docId : docSet) {</span>
<span class="nc" id="L1468">              Integer matchNumber = data.get(docId);</span>
<span class="nc bnc" id="L1469" title="All 2 branches missed.">              if (matchNumber != null) {</span>
<span class="nc" id="L1470">                list.position += matchNumber;</span>
              }
<span class="nc" id="L1472">            }</span>
<span class="nc" id="L1473">            list.total = list.position;</span>
          }
        }
<span class="nc" id="L1476">      }</span>
    }
<span class="nc" id="L1478">  }</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,
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, ArrayList&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="L1510" title="2 of 4 branches missed.">    if (mtasCodecInfo != null &amp;&amp; groupList != null) {</span>
      ArrayList&lt;Match&gt; matchList;
      HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt; matchData;
<span class="fc bfc" id="L1513" title="All 2 branches covered.">      for (ComponentGroup group : groupList) {</span>
<span class="fc" id="L1514">        group.dataCollector.setWithTotal();</span>
<span class="pc bpc" id="L1515" title="1 of 2 branches missed.">        if (group.prefixes.size() &gt; 0) {</span>
<span class="fc" id="L1516">          matchData = spansMatchData.get(group.spanQuery);</span>
<span class="fc" id="L1517">          HashSet&lt;String&gt; knownPrefixes = collectKnownPrefixes(fieldInfo);</span>
<span class="fc" id="L1518">          HashSet&lt;String&gt; intersectionPrefixes = collectIntersectionPrefixes(</span>
              fieldInfo);
<span class="fc" id="L1520">          boolean intersectionGroupPrefixes = intersectionPrefixes(group,</span>
              intersectionPrefixes);
<span class="fc" id="L1522">          boolean availablePrefixes = availablePrefixes(group, knownPrefixes);</span>
          // sort match lists
<span class="pc bpc" id="L1524" title="1 of 2 branches missed.">          if (!intersectionGroupPrefixes) {</span>
<span class="fc bfc" id="L1525" title="All 2 branches covered.">            for (Entry&lt;Integer,ArrayList&lt;Match&gt;&gt; entry : matchData.entrySet()) {</span>
<span class="fc" id="L1526">              sortMatchList(entry.getValue());</span>
<span class="fc" id="L1527">            }</span>
          }
          // init
<span class="fc" id="L1530">          group.dataCollector.initNewList(1);</span>
          int docId;

<span class="fc" id="L1533">          HashMap&lt;GroupHit, Long&gt; occurencesSum = new HashMap&lt;GroupHit, Long&gt;();</span>
<span class="fc" id="L1534">          HashMap&lt;GroupHit, Integer&gt; occurencesN = new HashMap&lt;GroupHit, Integer&gt;();</span>
<span class="fc" id="L1535">          HashSet&lt;GroupHit&gt; occurencesInCurrentDocument = new HashSet&lt;GroupHit&gt;();</span>

<span class="pc bpc" id="L1537" title="1 of 2 branches missed.">          if (!availablePrefixes) {</span>
<span class="nc" id="L1538">            HashMap&lt;Integer, GroupHit&gt; hits = new HashMap&lt;Integer, GroupHit&gt;();</span>
<span class="nc bnc" id="L1539" title="All 2 branches missed.">            for (int docCounter = 0; docCounter &lt; docSet.size(); docCounter++) {</span>
<span class="nc" id="L1540">              occurencesInCurrentDocument.clear();</span>
<span class="nc" id="L1541">              docId = docSet.get(docCounter);</span>
              GroupHit hit, hitKey;
<span class="nc bnc" id="L1543" title="All 2 branches missed.">              if (matchData != null</span>
<span class="nc bnc" id="L1544" title="All 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null</span>
<span class="nc bnc" id="L1545" title="All 2 branches missed.">                  &amp;&amp; matchList.size() &gt; 0) {</span>
<span class="nc" id="L1546">                Iterator&lt;Match&gt; it = matchList.listIterator();</span>
<span class="nc bnc" id="L1547" title="All 2 branches missed.">                while (it.hasNext()) {</span>
<span class="nc" id="L1548">                  Match m = it.next();</span>
<span class="nc" id="L1549">                  IntervalTreeNodeData&lt;String&gt; positionHit = createPositionHit(</span>
                      m, group);
<span class="nc" id="L1551">                  int length = m.endPosition - m.startPosition;</span>
<span class="nc" id="L1552">                  hitKey = null;</span>
<span class="nc bnc" id="L1553" title="All 2 branches missed.">                  if (!hits.containsKey(length)) {</span>
<span class="nc" id="L1554">                    hit = new GroupHit(positionHit.list, positionHit.start,</span>
                        positionHit.end, positionHit.hitStart,
                        positionHit.hitEnd, group, knownPrefixes);
<span class="nc" id="L1557">                    hits.put(length, hit);</span>
                  } else {
<span class="nc" id="L1559">                    hit = hits.get(length);</span>
<span class="nc bnc" id="L1560" title="All 2 branches missed.">                    for (GroupHit hitKeyItem : occurencesSum.keySet()) {</span>
<span class="nc bnc" id="L1561" title="All 2 branches missed.">                      if (hitKeyItem.equals(hit)) {</span>
<span class="nc" id="L1562">                        hitKey = hitKeyItem;</span>
<span class="nc" id="L1563">                        break;</span>
                      }
<span class="nc" id="L1565">                    }</span>
                  }
<span class="nc bnc" id="L1567" title="All 2 branches missed.">                  if (hitKey == null) {</span>
<span class="nc" id="L1568">                    occurencesSum.put(hit, Long.valueOf(1));</span>
<span class="nc" id="L1569">                    occurencesN.put(hit, 1);</span>
<span class="nc" id="L1570">                    occurencesInCurrentDocument.add(hit);</span>
                  } else {
<span class="nc" id="L1572">                    occurencesSum.put(hitKey, occurencesSum.get(hitKey) + 1);</span>
<span class="nc bnc" id="L1573" title="All 2 branches missed.">                    if (!occurencesInCurrentDocument.contains(hitKey)) {</span>
<span class="nc bnc" id="L1574" title="All 2 branches missed.">                      if (occurencesN.containsKey(hitKey)) {</span>
<span class="nc" id="L1575">                        occurencesN.put(hitKey, occurencesN.get(hitKey) + 1);</span>
                      } else {
<span class="nc" id="L1577">                        occurencesN.put(hitKey, 1);</span>
                      }
<span class="nc" id="L1579">                      occurencesInCurrentDocument.add(hitKey);</span>
                    }
                  }
<span class="nc" id="L1582">                }</span>
              }
            }

<span class="nc" id="L1586">          } else {</span>
<span class="fc" id="L1587">            int maximumNumberOfDocuments = 0;</span>
<span class="fc" id="L1588">            int boundaryMinimumNumberOfDocuments = 1;</span>
<span class="fc" id="L1589">            int boundaryMaximumNumberOfDocuments = 5;</span>
<span class="fc" id="L1590">            HashSet&lt;GroupHit&gt; administrationOccurrences = new HashSet&lt;GroupHit&gt;();</span>
<span class="fc bfc" id="L1591" title="All 2 branches covered.">            for (int docCounter = 0; docCounter &lt; docSet.size(); docCounter++) {</span>
<span class="fc" id="L1592">              occurencesInCurrentDocument.clear();</span>
<span class="fc" id="L1593">              docId = docSet.get(docCounter);</span>
<span class="pc bpc" id="L1594" title="1 of 2 branches missed.">              if (matchData != null</span>
<span class="pc bpc" id="L1595" title="1 of 2 branches missed.">                  &amp;&amp; (matchList = matchData.get(docId)) != null</span>
<span class="pc bpc" id="L1596" title="1 of 2 branches missed.">                  &amp;&amp; matchList.size() &gt; 0) {</span>
                // loop over matches
<span class="fc" id="L1598">                Iterator&lt;Match&gt; it = matchList.listIterator();</span>
<span class="fc" id="L1599">                ArrayList&lt;IntervalTreeNodeData&lt;String&gt;&gt; positionsHits = new ArrayList&lt;IntervalTreeNodeData&lt;String&gt;&gt;();</span>
<span class="fc bfc" id="L1600" title="All 2 branches covered.">                while (it.hasNext()) {</span>
<span class="fc" id="L1601">                  Match m = it.next();</span>
<span class="fc" id="L1602">                  positionsHits.add(createPositionHit(m, group));</span>
<span class="fc" id="L1603">                }</span>
<span class="fc" id="L1604">                mtasCodecInfo.collectTermsByPrefixesForListOfHitPositions(field,</span>
                    (docId - docBase), group.prefixes, positionsHits);
                // administration
<span class="fc bfc" id="L1607" title="All 2 branches covered.">                for (IntervalTreeNodeData&lt;String&gt; positionHit : positionsHits) {</span>
<span class="fc" id="L1608">                  GroupHit hit = new GroupHit(positionHit.list,</span>
                      positionHit.start, positionHit.end, positionHit.hitStart,
                      positionHit.hitEnd, group, knownPrefixes);
<span class="fc" id="L1611">                  GroupHit hitKey = null;</span>
<span class="fc bfc" id="L1612" title="All 2 branches covered.">                  for (GroupHit hitKeyItem : occurencesSum.keySet()) {</span>
<span class="fc bfc" id="L1613" title="All 2 branches covered.">                    if (hitKeyItem.equals(hit)) {</span>
<span class="fc" id="L1614">                      hitKey = hitKeyItem;</span>
<span class="fc" id="L1615">                      break;</span>
                    }
<span class="fc" id="L1617">                  }</span>
<span class="fc bfc" id="L1618" title="All 2 branches covered.">                  if (hitKey == null) {</span>
<span class="fc" id="L1619">                    occurencesSum.put(hit, Long.valueOf(1));</span>
<span class="fc" id="L1620">                    occurencesN.put(hit, 1);</span>
<span class="fc" id="L1621">                    occurencesInCurrentDocument.add(hit);</span>
                  } else {
<span class="fc" id="L1623">                    occurencesSum.put(hitKey, occurencesSum.get(hitKey) + 1);</span>
<span class="pc bpc" id="L1624" title="1 of 2 branches missed.">                    if (!occurencesInCurrentDocument.contains(hitKey)) {</span>
<span class="nc bnc" id="L1625" title="All 2 branches missed.">                      if (occurencesN.containsKey(hitKey)) {</span>
<span class="nc" id="L1626">                        occurencesN.put(hitKey, occurencesN.get(hitKey) + 1);</span>
                      } else {
<span class="nc" id="L1628">                        occurencesN.put(hitKey, 1);</span>
                      }
<span class="nc" id="L1630">                      occurencesInCurrentDocument.add(hitKey);</span>
                    }
                  }
<span class="fc" id="L1633">                }</span>
<span class="pc bpc" id="L1634" title="1 of 2 branches missed.">                if (!intersectionGroupPrefixes) {</span>
<span class="fc bfc" id="L1635" title="All 2 branches covered.">                  for (GroupHit groupHit : occurencesInCurrentDocument) {</span>
<span class="fc" id="L1636">                    int tmpNumber = occurencesN.get(groupHit);</span>
<span class="fc" id="L1637">                    maximumNumberOfDocuments = Math</span>
<span class="fc" id="L1638">                        .max(maximumNumberOfDocuments, tmpNumber);</span>
<span class="pc bpc" id="L1639" title="1 of 2 branches missed.">                    if (tmpNumber &gt; boundaryMinimumNumberOfDocuments) {</span>
<span class="nc" id="L1640">                      administrationOccurrences.add(groupHit);</span>
                    }
<span class="fc" id="L1642">                  }</span>
                  // collect spans
<span class="pc bpc" id="L1644" title="1 of 2 branches missed.">                  if (maximumNumberOfDocuments &gt; boundaryMaximumNumberOfDocuments) {</span>
<span class="nc bnc" id="L1645" title="All 2 branches missed.">                    if (administrationOccurrences.size() &gt; 0) {</span>
<span class="nc" id="L1646">                      HashMap&lt;GroupHit, Spans&gt; list = collectSpansForOccurences(</span>
                          administrationOccurrences, knownPrefixes, field,
                          mtasCodecInfo, searcher, lrc);
<span class="nc bnc" id="L1649" title="All 2 branches missed.">                      if (list.size() &gt; 0) {</span>
<span class="nc" id="L1650">                        collectGroupUsingSpans(list, docSet, docBase,</span>
                            docCounter, matchData, occurencesSum, occurencesN);
                      }
                    }
<span class="nc" id="L1654">                    administrationOccurrences.clear();</span>
<span class="nc" id="L1655">                    maximumNumberOfDocuments = 0;</span>
<span class="nc" id="L1656">                    boundaryMinimumNumberOfDocuments = (int) Math</span>
<span class="nc" id="L1657">                        .ceil(boundaryMinimumNumberOfDocuments * 1.2);</span>
<span class="nc" id="L1658">                    boundaryMaximumNumberOfDocuments = (int) Math</span>
<span class="nc" id="L1659">                        .ceil(boundaryMaximumNumberOfDocuments * 1.2);</span>
                  }
                }
              }
            }
          }

<span class="fc bfc" id="L1666" title="All 2 branches covered.">          for (Entry&lt;GroupHit,Long&gt; entry : occurencesSum.entrySet()) {</span>
<span class="fc" id="L1667">            group.dataCollector.add(entry.getKey().toString(), entry.getValue(),</span>
<span class="fc" id="L1668">                occurencesN.get(entry.getKey()));</span>
<span class="fc" id="L1669">          }</span>
<span class="fc" id="L1670">          group.dataCollector.closeNewList();</span>
        }
<span class="fc" id="L1672">      }</span>
    }
<span class="fc" id="L1674">  }</span>

  /**
   * Available prefixes.
   *
   * @param group
   *          the group
   * @param knownPrefixes
   *          the known prefixes
   * @return true, if successful
   */
  private static boolean availablePrefixes(ComponentGroup group,
      HashSet&lt;String&gt; knownPrefixes) {
<span class="pc bpc" id="L1687" title="1 of 2 branches missed.">    for (String prefix : group.prefixes) {</span>
<span class="pc bpc" id="L1688" title="1 of 2 branches missed.">      if (knownPrefixes.contains(prefix)) {</span>
<span class="fc" id="L1689">        return true;</span>
      }
<span class="nc" id="L1691">    }</span>
<span class="nc" id="L1692">    return false;</span>
  }

  /**
   * Intersection prefixes.
   *
   * @param group
   *          the group
   * @param intersectionPrefixes
   *          the intersection prefixes
   * @return true, if successful
   */
  private static boolean intersectionPrefixes(ComponentGroup group,
      HashSet&lt;String&gt; intersectionPrefixes) {
<span class="fc bfc" id="L1706" title="All 2 branches covered.">    for (String prefix : group.prefixes) {</span>
<span class="pc bpc" id="L1707" title="1 of 2 branches missed.">      if (intersectionPrefixes.contains(prefix)) {</span>
<span class="nc" id="L1708">        return true;</span>
      }
<span class="fc" id="L1710">    }</span>
<span class="fc" id="L1711">    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="L1725">    Integer start = null, end = null;</span>
<span class="pc bpc" id="L1726" title="5 of 6 branches missed.">    if (group.hitInside != null || group.hitInsideLeft != null</span>
        || group.hitInsideRight != null) {
<span class="fc" id="L1728">      start = m.startPosition;</span>
<span class="fc" id="L1729">      end = m.endPosition - 1;</span>
    } else {
<span class="nc" id="L1731">      start = null;</span>
<span class="nc" id="L1732">      end = null;</span>
    }
<span class="pc bpc" id="L1734" title="1 of 2 branches missed.">    if (group.hitLeft != null) {</span>
<span class="nc" id="L1735">      start = m.startPosition;</span>
<span class="nc" id="L1736">      end = Math.max(m.startPosition + group.hitLeft.length - 1,</span>
          m.endPosition - 1);
    }
<span class="pc bpc" id="L1739" title="1 of 2 branches missed.">    if (group.hitRight != null) {</span>
<span class="nc" id="L1740">      start = Math.min(m.endPosition - group.hitRight.length + 1,</span>
          m.startPosition);
<span class="nc bnc" id="L1742" title="All 2 branches missed.">      end = end == null ? m.endPosition : Math.max(end, m.endPosition);</span>
    }
<span class="pc bpc" id="L1744" title="1 of 2 branches missed.">    if (group.left != null) {</span>
<span class="nc bnc" id="L1745" title="All 2 branches missed.">      start = start == null ? m.startPosition - group.left.length</span>
<span class="nc" id="L1746">          : Math.min(m.startPosition - group.left.length, start);</span>
<span class="nc bnc" id="L1747" title="All 2 branches missed.">      end = end == null ? m.startPosition - 1</span>
<span class="nc" id="L1748">          : Math.max(m.startPosition - 1, end);</span>
    }
<span class="pc bpc" id="L1750" title="1 of 2 branches missed.">    if (group.right != null) {</span>
<span class="nc bnc" id="L1751" title="All 2 branches missed.">      start = start == null ? m.endPosition : Math.min(m.endPosition, start);</span>
<span class="nc bnc" id="L1752" title="All 2 branches missed.">      end = end == null ? m.endPosition + group.right.length</span>
<span class="nc" id="L1753">          : Math.max(m.endPosition + group.right.length, end);</span>
    }
<span class="fc" id="L1755">    return new IntervalTreeNodeData&lt;String&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(HashMap&lt;GroupHit, Spans&gt; list,
      List&lt;Integer&gt; docSet, int docBase, int docCounter,
      HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt; matchData,
      HashMap&lt;GroupHit, Long&gt; occurencesSum,
      HashMap&lt;GroupHit, Integer&gt; occurencesN) throws IOException {
<span class="nc" id="L1785">    int total = 0;</span>
<span class="nc bnc" id="L1786" title="All 2 branches missed.">    if (docCounter + 1 &lt; docSet.size()) {</span>
      // initialize
<span class="nc" id="L1788">      int nextDocCounter = docCounter + 1;</span>
<span class="nc" id="L1789">      long[] subSum = new long[list.size()];</span>
<span class="nc" id="L1790">      int[] subN = new int[list.size()];</span>
<span class="nc" id="L1791">      boolean[] newNextDocs = new boolean[list.size()];</span>
      boolean newNextDoc;
<span class="nc" id="L1793">      int[] spansNextDoc = new int[list.size()];</span>
<span class="nc" id="L1794">      int nextDoc = 0;</span>
      ArrayList&lt;Match&gt; matchList;
<span class="nc" id="L1796">      GroupHit[] hitList = list.keySet().toArray(new GroupHit[list.size()]);</span>
<span class="nc" id="L1797">      Spans[] spansList = new Spans[list.size()];</span>
<span class="nc" id="L1798">      boolean[] finishedSpansList = new boolean[list.size()];</span>
<span class="nc" id="L1799">      newNextDoc = true;</span>
      // advance spans, find nextDoc
<span class="nc bnc" id="L1801" title="All 2 branches missed.">      for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc" id="L1802">        newNextDocs[i] = true;</span>
<span class="nc" id="L1803">        spansList[i] = list.get(hitList[i]);</span>
<span class="nc" id="L1804">        spansNextDoc[i] = spansList[i]</span>
<span class="nc" id="L1805">            .advance(docSet.get(nextDocCounter) - docBase);</span>
<span class="nc bnc" id="L1806" title="All 2 branches missed.">        nextDoc = (i == 0) ? spansNextDoc[i]</span>
<span class="nc" id="L1807">            : Math.min(nextDoc, spansNextDoc[i]);</span>
      }
      // loop over future documents
<span class="nc bnc" id="L1810" title="All 2 branches missed.">      while (nextDoc &lt; DocIdSetIterator.NO_MORE_DOCS) {</span>
        // find matches for next document
<span class="nc bnc" id="L1812" title="All 2 branches missed.">        while (nextDocCounter &lt; docSet.size()</span>
<span class="nc bnc" id="L1813" title="All 2 branches missed.">            &amp;&amp; docSet.get(nextDocCounter) &lt; (nextDoc + docBase)) {</span>
<span class="nc" id="L1814">          nextDocCounter++;</span>
        }
        // finish, if no more docs in set
<span class="nc bnc" id="L1817" title="All 2 branches missed.">        if (nextDocCounter &gt;= docSet.size()) {</span>
<span class="nc" id="L1818">          break;</span>
        }
        // go to the matches
<span class="nc bnc" id="L1821" title="All 2 branches missed.">        if (docSet.get(nextDocCounter) == nextDoc + docBase) {</span>
<span class="nc" id="L1822">          matchList = matchData.get(nextDoc + docBase);</span>
<span class="nc bnc" id="L1823" title="All 4 branches missed.">          if (matchList != null &amp;&amp; matchList.size() &gt; 0) {</span>
            // initialize
<span class="nc" id="L1825">            int currentMatchPosition = 0;</span>
<span class="nc" id="L1826">            int lastMatchStartPosition = matchList</span>
<span class="nc" id="L1827">                .get(matchList.size() - 1).startPosition;</span>
<span class="nc" id="L1828">            ArrayList&lt;Match&gt; newMatchList = new ArrayList&lt;Match&gt;(</span>
<span class="nc" id="L1829">                matchList.size());</span>
<span class="nc" id="L1830">            int currentSpanPosition = Spans.NO_MORE_POSITIONS;</span>
            // check and initialize for each span
<span class="nc bnc" id="L1832" title="All 2 branches missed.">            for (int i = 0; i &lt; spansList.length; i++) {</span>
<span class="nc bnc" id="L1833" title="All 2 branches missed.">              if (spansList[i].docID() == nextDoc) {</span>
<span class="nc" id="L1834">                int tmpStartPosition = spansList[i].nextStartPosition();</span>
<span class="nc bnc" id="L1835" title="All 2 branches missed.">                if (tmpStartPosition &lt; Spans.NO_MORE_POSITIONS) {</span>
<span class="nc" id="L1836">                  finishedSpansList[i] = false;</span>
                } else {
<span class="nc" id="L1838">                  finishedSpansList[i] = true;</span>
                }
                // compute position
<span class="nc bnc" id="L1841" title="All 2 branches missed.">                currentSpanPosition = (currentSpanPosition == Spans.NO_MORE_POSITIONS)</span>
                    ? tmpStartPosition
<span class="nc" id="L1843">                    : Math.min(currentSpanPosition, tmpStartPosition);</span>
<span class="nc" id="L1844">              } else {</span>
<span class="nc" id="L1845">                finishedSpansList[i] = true;</span>
              }
            }
            // loop over matches
<span class="nc bnc" id="L1849" title="All 4 branches missed.">            while (currentMatchPosition &lt; matchList.size()</span>
                &amp;&amp; currentSpanPosition &lt; Spans.NO_MORE_POSITIONS) {

<span class="nc" id="L1852">              if (currentSpanPosition &lt; matchList</span>
<span class="nc bnc" id="L1853" title="All 2 branches missed.">                  .get(currentMatchPosition).startPosition) {</span>
                // do nothing, match not reached
<span class="nc bnc" id="L1855" title="All 2 branches missed.">              } else if (currentSpanPosition &gt; lastMatchStartPosition) {</span>
                // finish, past last match
<span class="nc" id="L1857">                break;</span>
              } else {
                // advance matches
<span class="nc bnc" id="L1860" title="All 2 branches missed.">                while (currentMatchPosition &lt; matchList.size()</span>
                    &amp;&amp; currentSpanPosition &gt; matchList
<span class="nc bnc" id="L1862" title="All 2 branches missed.">                        .get(currentMatchPosition).startPosition) {</span>
                  // store current match, not relevant
<span class="nc" id="L1864">                  newMatchList.add(matchList.get(currentMatchPosition));</span>
<span class="nc" id="L1865">                  currentMatchPosition++;</span>
                }
                // equal startPosition
<span class="nc bnc" id="L1868" title="All 2 branches missed.">                while (currentMatchPosition &lt; matchList.size()</span>
                    &amp;&amp; currentSpanPosition == matchList
<span class="nc bnc" id="L1870" title="All 2 branches missed.">                        .get(currentMatchPosition).startPosition) {</span>
                  // check for each span
<span class="nc bnc" id="L1872" 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="L1874" title="All 4 branches missed.">                    if (!finishedSpansList[i] &amp;&amp; spansList[i].docID() == nextDoc</span>
<span class="nc" id="L1875">                        &amp;&amp; spansList[i].startPosition() == matchList</span>
<span class="nc bnc" id="L1876" title="All 2 branches missed.">                            .get(currentMatchPosition).startPosition</span>
<span class="nc" id="L1877">                        &amp;&amp; spansList[i].endPosition() == matchList</span>
<span class="nc bnc" id="L1878" title="All 2 branches missed.">                            .get(currentMatchPosition).endPosition) {</span>
                      // administration
<span class="nc" id="L1880">                      total++;</span>
<span class="nc" id="L1881">                      subSum[i]++;</span>
<span class="nc bnc" id="L1882" title="All 2 branches missed.">                      if (newNextDocs[i]) {</span>
<span class="nc" id="L1883">                        subN[i]++;</span>
<span class="nc" id="L1884">                        newNextDocs[i] = false;</span>
<span class="nc" id="L1885">                        newNextDoc = false;</span>
                      }
<span class="nc bnc" id="L1887" title="All 2 branches missed.">                    } else if (!finishedSpansList[i]</span>
<span class="nc bnc" id="L1888" title="All 2 branches missed.">                        &amp;&amp; spansList[i].docID() == nextDoc</span>
<span class="nc" id="L1889">                        &amp;&amp; spansList[i].startPosition() == matchList</span>
<span class="nc bnc" id="L1890" title="All 2 branches missed.">                            .get(currentMatchPosition).startPosition) {</span>
                      // no match, store
<span class="nc" id="L1892">                      newMatchList.add(matchList.get(currentMatchPosition));</span>
                    }
                  }
<span class="nc" id="L1895">                  currentMatchPosition++;</span>
                }
              }

              // advance spans
<span class="nc bnc" id="L1900" title="All 2 branches missed.">              if (currentMatchPosition &lt; matchList.size()) {</span>
<span class="nc" id="L1901">                currentSpanPosition = Spans.NO_MORE_POSITIONS;</span>
<span class="nc bnc" id="L1902" title="All 2 branches missed.">                for (int i = 0; i &lt; spansList.length; i++) {</span>
<span class="nc bnc" id="L1903" title="All 2 branches missed.">                  if (!finishedSpansList[i]</span>
<span class="nc bnc" id="L1904" title="All 2 branches missed.">                      &amp;&amp; (spansList[i].docID() == nextDoc)) {</span>
<span class="nc bnc" id="L1905" title="All 2 branches missed.">                    while (!finishedSpansList[i]</span>
<span class="nc" id="L1906">                        &amp;&amp; spansList[i].startPosition() &lt; matchList</span>
<span class="nc bnc" id="L1907" title="All 2 branches missed.">                            .get(currentMatchPosition).startPosition) {</span>
<span class="nc" id="L1908">                      int tmpStartPosition = spansList[i].nextStartPosition();</span>
<span class="nc bnc" id="L1909" title="All 2 branches missed.">                      if (tmpStartPosition == Spans.NO_MORE_POSITIONS) {</span>
<span class="nc" id="L1910">                        finishedSpansList[i] = true;</span>
                      }
<span class="nc" id="L1912">                    }</span>
<span class="nc bnc" id="L1913" title="All 2 branches missed.">                    if (!finishedSpansList[i]) {</span>
<span class="nc bnc" id="L1914" title="All 2 branches missed.">                      currentSpanPosition = (currentSpanPosition == Spans.NO_MORE_POSITIONS)</span>
<span class="nc" id="L1915">                          ? spansList[i].startPosition()</span>
<span class="nc" id="L1916">                          : Math.min(currentSpanPosition,</span>
<span class="nc" id="L1917">                              spansList[i].startPosition());</span>
                    }
                  } else {
<span class="nc" id="L1920">                    finishedSpansList[i] = true;</span>
                  }
                }
              }
            }
<span class="nc bnc" id="L1925" title="All 2 branches missed.">            if (!newNextDoc) {</span>
              // add other matches
<span class="nc bnc" id="L1927" title="All 2 branches missed.">              while (currentMatchPosition &lt; matchList.size()) {</span>
<span class="nc" id="L1928">                newMatchList.add(matchList.get(currentMatchPosition));</span>
<span class="nc" id="L1929">                currentMatchPosition++;</span>
              }
              // update administration
<span class="nc bnc" id="L1932" title="All 2 branches missed.">              if (newMatchList.size() &gt; 0) {</span>
<span class="nc" id="L1933">                matchData.put(nextDoc + docBase, newMatchList);</span>
              } else {
<span class="nc" id="L1935">                matchData.put(nextDoc + docBase, null);</span>
              }
            }
          }
        }
        // advance to next document
<span class="nc" id="L1941">        nextDocCounter++;</span>
<span class="nc" id="L1942">        newNextDoc = true;</span>
<span class="nc bnc" id="L1943" title="All 2 branches missed.">        for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc" id="L1944">          newNextDocs[i] = true;</span>
        }
        // advance spans
<span class="nc bnc" id="L1947" title="All 2 branches missed.">        if (nextDocCounter &lt; docSet.size()) {</span>
<span class="nc" id="L1948">          nextDoc = Spans.NO_MORE_DOCS;</span>
          // advance spans
<span class="nc bnc" id="L1950" title="All 2 branches missed.">          for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc bnc" id="L1951" title="All 2 branches missed.">            if (spansNextDoc[i] &lt; (docSet.get(nextDocCounter) - docBase)) {</span>
<span class="nc" id="L1952">              spansNextDoc[i] = spansList[i]</span>
<span class="nc" id="L1953">                  .advance(docSet.get(nextDocCounter) - docBase);</span>
            }
<span class="nc bnc" id="L1955" title="All 2 branches missed.">            if (spansNextDoc[i] &lt; Spans.NO_MORE_DOCS) {</span>
<span class="nc bnc" id="L1956" title="All 2 branches missed.">              nextDoc = (nextDoc == Spans.NO_MORE_DOCS) ? spansNextDoc[i]</span>
<span class="nc" id="L1957">                  : Math.min(nextDoc, spansNextDoc[i]);</span>
            }
          }
        }
      }
      // update administration
<span class="nc bnc" id="L1963" title="All 2 branches missed.">      for (int i = 0; i &lt; hitList.length; i++) {</span>
<span class="nc bnc" id="L1964" title="All 2 branches missed.">        if (subSum[i] &gt; 0) {</span>
<span class="nc bnc" id="L1965" title="All 2 branches missed.">          if (occurencesSum.containsKey(hitList[i])) {</span>
<span class="nc" id="L1966">            occurencesSum.put(hitList[i],</span>
<span class="nc" id="L1967">                occurencesSum.get(hitList[i]) + subSum[i]);</span>
<span class="nc" id="L1968">            occurencesN.put(hitList[i], occurencesN.get(hitList[i]) + subN[i]);</span>
          }
        }
      }
    }
<span class="nc" id="L1973">    return total;</span>
  }

  /**
   * Sort match list.
   *
   * @param list
   *          the list
   */
  private static void sortMatchList(ArrayList&lt;Match&gt; list) {
<span class="pc bpc" id="L1983" title="1 of 2 branches missed.">    if (list != null) {</span>
      // light sorting on start position
<span class="fc" id="L1985">      Collections.sort(list, new Comparator&lt;Match&gt;() {</span>
        @Override
        public int compare(Match m1, Match m2) {
<span class="pc bpc" id="L1988" title="1 of 2 branches missed.">          if (m1.startPosition &lt; m2.startPosition) {</span>
<span class="nc" id="L1989">            return -1;</span>
<span class="pc bpc" id="L1990" title="1 of 2 branches missed.">          } else if (m1.startPosition &gt; m2.startPosition) {</span>
<span class="fc" id="L1991">            return 1;</span>
          } else {
<span class="nc" id="L1993">            return 0;</span>
          }
        }
      });
    }
<span class="fc" id="L1998">  }</span>

  /**
   * Creates the document.
   *
   * @param documentList
   *          the document list
   * @param docList
   *          the doc list
   * @param field
   *          the field
   * @param docBase
   *          the doc base
   * @param uniqueKeyField
   *          the unique key field
   * @param searcher
   *          the searcher
   * @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 createDocument(List&lt;ComponentDocument&gt; documentList,
      List&lt;Integer&gt; docList, String field, int docBase, String uniqueKeyField,
      IndexSearcher searcher, Terms t, LeafReader r, LeafReaderContext lrc)
      throws IOException {
<span class="nc bnc" id="L2028" title="All 2 branches missed.">    if (documentList != null) {</span>
<span class="nc" id="L2029">      TreeSet&lt;String&gt; listStatsItems = CodecUtil.createStatsItems(&quot;sum&quot;);</span>
<span class="nc" id="L2030">      String listStatsType = CodecUtil.createStatsType(listStatsItems,</span>
          CodecUtil.STATS_TYPE_SUM, null);
<span class="nc bnc" id="L2032" title="All 2 branches missed.">      for (ComponentDocument document : documentList) {</span>
        // initialize
<span class="nc bnc" id="L2034" title="All 2 branches missed.">        for (int docId : docList) {</span>
          // get unique id
<span class="nc" id="L2036">          Document doc = searcher.doc(docId,</span>
<span class="nc" id="L2037">              new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L2038">          IndexableField indxfld = doc.getField(uniqueKeyField);</span>
          // get other doc info
<span class="nc bnc" id="L2040" title="All 2 branches missed.">          if (indxfld != null) {</span>
<span class="nc" id="L2041">            document.uniqueKey.put(docId, indxfld.stringValue());</span>
<span class="nc" id="L2042">            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="L2046">            document.statsData.put(docId, stats);</span>
<span class="nc bnc" id="L2047" title="All 2 branches missed.">            if (document.statsList != null) {</span>
              MtasDataCollector&lt;?, ?&gt; list;
<span class="nc bnc" id="L2049" title="All 2 branches missed.">              if (document.listExpand) {</span>
<span class="nc" id="L2050">                TreeSet&lt;String&gt;[] baseStatsItems = new TreeSet[] {</span>
                    listStatsItems };
<span class="nc" id="L2052">                list = DataCollector.getCollector(</span>
                    DataCollector.COLLECTOR_TYPE_LIST, CodecUtil.DATA_TYPE_LONG,
                    listStatsType, listStatsItems, CodecUtil.STATS_TYPE_SUM,
<span class="nc" id="L2055">                    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="L2059">                    Arrays.copyOfRange(baseStatsItems, 0,</span>
                        baseStatsItems.length),
                    new String[] { CodecUtil.STATS_TYPE_SUM },
<span class="nc" id="L2062">                    new String[] { CodecUtil.SORT_DESC }, new Integer[] { 0 },</span>
<span class="nc" id="L2063">                    new Integer[] { document.listExpandNumber }, null, null);</span>
<span class="nc" id="L2064">              } else {</span>
<span class="nc" id="L2065">                list = DataCollector.getCollector(</span>
                    DataCollector.COLLECTOR_TYPE_LIST, CodecUtil.DATA_TYPE_LONG,
                    listStatsType, listStatsItems, CodecUtil.STATS_TYPE_SUM,
<span class="nc" id="L2068">                    CodecUtil.SORT_DESC, 0, document.listNumber, null, null);</span>
              }
<span class="nc" id="L2070">              document.statsList.put(docId, list);</span>
            }
          }
<span class="nc" id="L2073">        }</span>
<span class="nc" id="L2074">      }</span>
      // collect
<span class="nc bnc" id="L2076" title="All 2 branches missed.">      if (t != null) {</span>
        BytesRef term;
        TermsEnum termsEnum;
<span class="nc" id="L2079">        PostingsEnum postingsEnum = null;</span>
        // loop over termvectors
<span class="nc bnc" id="L2081" title="All 2 branches missed.">        for (ComponentDocument document : documentList) {</span>

          List&lt;CompiledAutomaton&gt; listAutomata;
          HashMap&lt;String, Automaton&gt; automatonMap;
          HashMap&lt;String, ByteRunAutomaton&gt; byteRunAutomatonMap;
<span class="nc bnc" id="L2086" title="All 2 branches missed.">          if (document.list == null) {</span>
<span class="nc" id="L2087">            automatonMap = null;</span>
<span class="nc" id="L2088">            byteRunAutomatonMap = null;</span>
<span class="nc" id="L2089">            listAutomata = new ArrayList&lt;CompiledAutomaton&gt;();</span>
            CompiledAutomaton compiledAutomaton;
            Automaton automaton;
<span class="nc bnc" id="L2092" title="All 4 branches missed.">            if ((document.regexp == null) || (document.regexp.isEmpty())) {</span>
<span class="nc" id="L2093">              RegExp re = new RegExp(</span>
                  document.prefix + MtasToken.DELIMITER + &quot;.*&quot;);
<span class="nc" id="L2095">              automaton = re.toAutomaton();</span>
<span class="nc" id="L2096">            } else {</span>
<span class="nc" id="L2097">              RegExp re = new RegExp(document.prefix + MtasToken.DELIMITER</span>
                  + document.regexp + &quot;\u0000*&quot;);
<span class="nc" id="L2099">              automaton = re.toAutomaton();</span>
            }
<span class="nc" id="L2101">            compiledAutomaton = new CompiledAutomaton(automaton);</span>
<span class="nc" id="L2102">            listAutomata.add(compiledAutomaton);</span>
<span class="nc" id="L2103">          } else {</span>
<span class="nc bnc" id="L2104" title="All 2 branches missed.">            automatonMap = MtasToken.createAutomatonMap(document.prefix,</span>
                new ArrayList&lt;String&gt;(document.list),
<span class="nc" id="L2106">                document.listRegexp ? false : true);</span>
<span class="nc" id="L2107">            byteRunAutomatonMap = MtasToken.byteRunAutomatonMap(automatonMap);</span>
<span class="nc" id="L2108">            listAutomata = MtasToken.createAutomata(document.prefix,</span>
                document.regexp, automatonMap);
          }
<span class="nc" id="L2111">          List&lt;ByteRunAutomaton&gt; ignoreByteRunAutomatonList = null;</span>
<span class="nc bnc" id="L2112" title="All 2 branches missed.">          if ((document.ignoreRegexp != null)</span>
<span class="nc bnc" id="L2113" title="All 2 branches missed.">              &amp;&amp; (!document.ignoreRegexp.isEmpty())) {</span>
<span class="nc" id="L2114">            ignoreByteRunAutomatonList = new ArrayList&lt;ByteRunAutomaton&gt;();</span>
<span class="nc" id="L2115">            RegExp re = new RegExp(document.prefix + MtasToken.DELIMITER</span>
                + document.ignoreRegexp + &quot;\u0000*&quot;);
<span class="nc" id="L2117">            ignoreByteRunAutomatonList</span>
<span class="nc" id="L2118">                .add(new ByteRunAutomaton(re.toAutomaton()));</span>
          }
<span class="nc bnc" id="L2120" title="All 2 branches missed.">          if (document.ignoreList != null) {</span>
<span class="nc bnc" id="L2121" title="All 2 branches missed.">            if (ignoreByteRunAutomatonList == null) {</span>
<span class="nc" id="L2122">              ignoreByteRunAutomatonList = new ArrayList&lt;ByteRunAutomaton&gt;();</span>
            }
<span class="nc bnc" id="L2124" title="All 2 branches missed.">            HashMap&lt;String, Automaton&gt; list = MtasToken.createAutomatonMap(</span>
                document.prefix, new ArrayList&lt;String&gt;(document.ignoreList),
<span class="nc" id="L2126">                document.ignoreListRegexp ? false : true);</span>
<span class="nc bnc" id="L2127" title="All 2 branches missed.">            for (Automaton automaton : list.values()) {</span>
<span class="nc" id="L2128">              ignoreByteRunAutomatonList.add(new ByteRunAutomaton(automaton));</span>
<span class="nc" id="L2129">            }</span>
          }

<span class="nc bnc" id="L2132" title="All 2 branches missed.">          for (CompiledAutomaton compiledAutomaton : listAutomata) {</span>
<span class="nc" id="L2133">            if (!compiledAutomaton.type</span>
<span class="nc bnc" id="L2134" title="All 2 branches missed.">                .equals(CompiledAutomaton.AUTOMATON_TYPE.NONE)) {</span>
<span class="nc" id="L2135">              termsEnum = t.intersect(compiledAutomaton, null);</span>
              // init
<span class="nc" id="L2137">              int initBaseSize = Math.min((int) t.size(), 1000);</span>
<span class="nc bnc" id="L2138" title="All 2 branches missed.">              int initListSize = document.statsList != null</span>
<span class="nc" id="L2139">                  ? Math.min(document.statsList.size(), initBaseSize)</span>
                  : initBaseSize;
<span class="nc" id="L2141">              HashSet&lt;MtasDataCollector&lt;?, ?&gt;&gt; initialised = new HashSet&lt;MtasDataCollector&lt;?, ?&gt;&gt;();</span>
<span class="nc bnc" id="L2142" title="All 2 branches missed.">              for (int docId : docList) {</span>
<span class="nc" id="L2143">                document.statsData.get(docId).initNewList(1);</span>
<span class="nc" id="L2144">                initialised.add(document.statsData.get(docId));</span>
<span class="nc bnc" id="L2145" title="All 2 branches missed.">                if (document.statsList != null</span>
<span class="nc bnc" id="L2146" title="All 2 branches missed.">                    &amp;&amp; document.statsList.size() &gt; 0) {</span>
<span class="nc" id="L2147">                  document.statsList.get(docId).initNewList(initListSize);</span>
<span class="nc" id="L2148">                  initialised.add(document.statsList.get(docId));</span>
                }
<span class="nc" id="L2150">              }</span>
              // fill
              int termDocId;
              boolean acceptedTerm;
<span class="nc bnc" id="L2154" title="All 2 branches missed.">              while ((term = termsEnum.next()) != null) {</span>
<span class="nc" id="L2155">                Iterator&lt;Integer&gt; docIterator = docList.iterator();</span>
<span class="nc" id="L2156">                postingsEnum = termsEnum.postings(postingsEnum,</span>
                    PostingsEnum.FREQS);
<span class="nc" id="L2158">                termDocId = -1;</span>
<span class="nc" id="L2159">                acceptedTerm = true;</span>
<span class="nc bnc" id="L2160" title="All 2 branches missed.">                if (ignoreByteRunAutomatonList != null) {</span>
<span class="nc bnc" id="L2161" title="All 2 branches missed.">                  for (ByteRunAutomaton ignoreByteRunAutomaton : ignoreByteRunAutomatonList) {</span>
<span class="nc bnc" id="L2162" title="All 2 branches missed.">                    if (ignoreByteRunAutomaton.run(term.bytes, term.offset,</span>
                        term.length)) {
<span class="nc" id="L2164">                      acceptedTerm = false;</span>
<span class="nc" id="L2165">                      break;</span>
                    }
<span class="nc" id="L2167">                  }</span>
                }
<span class="nc bnc" id="L2169" title="All 2 branches missed.">                if (acceptedTerm) {</span>
<span class="nc bnc" id="L2170" title="All 2 branches missed.">                  while (docIterator.hasNext()) {</span>
<span class="nc" id="L2171">                    int segmentDocId = docIterator.next() - lrc.docBase;</span>
<span class="nc bnc" id="L2172" title="All 2 branches missed.">                    if (segmentDocId &gt;= termDocId) {</span>
<span class="nc bnc" id="L2173" title="All 2 branches missed.">                      if ((segmentDocId == termDocId)</span>
                          || ((termDocId = postingsEnum
<span class="nc bnc" id="L2175" title="All 2 branches missed.">                              .advance(segmentDocId)) == segmentDocId)) {</span>
                        // register stats
<span class="nc" id="L2177">                        document.statsData.get(segmentDocId + lrc.docBase)</span>
<span class="nc" id="L2178">                            .add(new long[] { postingsEnum.freq() }, 1);</span>
                        // register list
<span class="nc bnc" id="L2180" title="All 2 branches missed.">                        if (document.statsList != null) {</span>
<span class="nc bnc" id="L2181" title="All 2 branches missed.">                          if (automatonMap != null) {</span>
                            MtasDataCollector&lt;?, ?&gt; dataCollector,
                                subSataCollector;
<span class="nc bnc" id="L2184" title="All 2 branches missed.">                            for (Entry&lt;String, ByteRunAutomaton&gt; entry : byteRunAutomatonMap.entrySet()) {</span>
<span class="nc" id="L2185">                              ByteRunAutomaton bra = entry.getValue();</span>
<span class="nc bnc" id="L2186" title="All 2 branches missed.">                              if (bra.run(term.bytes, term.offset,</span>
                                  term.length)) {
<span class="nc" id="L2188">                                dataCollector = document.statsList</span>
<span class="nc" id="L2189">                                    .get(segmentDocId + lrc.docBase);</span>
<span class="nc" id="L2190">                                subSataCollector = dataCollector.add(entry.getKey(),</span>
<span class="nc" id="L2191">                                    new long[] { postingsEnum.freq() }, 1);</span>
<span class="nc bnc" id="L2192" title="All 4 branches missed.">                                if (document.listExpand</span>
                                    &amp;&amp; subSataCollector != null) {
<span class="nc bnc" id="L2194" title="All 2 branches missed.">                                  if (!initialised.contains(subSataCollector)) {</span>
<span class="nc" id="L2195">                                    subSataCollector.initNewList(initBaseSize);</span>
<span class="nc" id="L2196">                                    initialised.add(subSataCollector);</span>
                                  }
<span class="nc" id="L2198">                                  subSataCollector.add(</span>
<span class="nc" id="L2199">                                      MtasToken.getPostfixFromValue(term),</span>
<span class="nc" id="L2200">                                      new long[] { postingsEnum.freq() }, 1);</span>
                                }
                              }
<span class="nc" id="L2203">                            }</span>
                          } else {
<span class="nc" id="L2205">                            document.statsList.get(segmentDocId + lrc.docBase)</span>
<span class="nc" id="L2206">                                .add(MtasToken.getPostfixFromValue(term),</span>
<span class="nc" id="L2207">                                    new long[] { postingsEnum.freq() }, 1);</span>
                          }
                        }
                      }
                    }
<span class="nc" id="L2212">                  }</span>
                }
<span class="nc" id="L2214">              }</span>
              // close
<span class="nc bnc" id="L2216" title="All 2 branches missed.">              for (MtasDataCollector&lt;?, ?&gt; item : initialised) {</span>
<span class="nc" id="L2217">                item.closeNewList();</span>
<span class="nc" id="L2218">              }</span>
<span class="nc" id="L2219">              initialised.clear();</span>
            }
<span class="nc" id="L2221">          }</span>
<span class="nc" id="L2222">        }</span>
      }
    }
<span class="nc" id="L2225">  }</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,
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, ArrayList&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="L2253" title="All 2 branches missed.">    if (kwicList != null) {</span>
<span class="nc bnc" id="L2254" title="All 2 branches missed.">      for (ComponentKwic kwic : kwicList) {</span>
<span class="nc" id="L2255">        HashMap&lt;Integer, ArrayList&lt;Match&gt;&gt; matchData = spansMatchData</span>
<span class="nc" id="L2256">            .get(kwic.query);</span>
        ArrayList&lt;Match&gt; matchList;
<span class="nc bnc" id="L2258" title="All 2 branches missed.">        if (kwic.output.equals(ComponentKwic.KWIC_OUTPUT_HIT)) {</span>
<span class="nc bnc" id="L2259" title="All 2 branches missed.">          for (int docId : docList) {</span>
<span class="nc bnc" id="L2260" title="All 2 branches missed.">            if (matchData != null</span>
<span class="nc bnc" id="L2261" title="All 2 branches missed.">                &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
              // get unique id
<span class="nc" id="L2263">              Document doc = searcher.doc(docId,</span>
<span class="nc" id="L2264">                  new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
<span class="nc" id="L2265">              IndexableField indxfld = doc.getField(uniqueKeyField);</span>
              // get other doc info
<span class="nc bnc" id="L2267" title="All 2 branches missed.">              if (indxfld != null) {</span>
<span class="nc" id="L2268">                kwic.uniqueKey.put(docId, indxfld.stringValue());</span>
              }
<span class="nc" id="L2270">              kwic.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L2271">              IndexDoc mDoc = mtasCodecInfo.getDoc(field, (docId - docBase));</span>
<span class="nc bnc" id="L2272" title="All 2 branches missed.">              if (mDoc != null) {</span>
<span class="nc" id="L2273">                kwic.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L2274">                kwic.maxPosition.put(docId, mDoc.maxPosition);</span>
              }
              // kwiclist
<span class="nc" id="L2277">              ArrayList&lt;KwicHit&gt; kwicItemList = new ArrayList&lt;KwicHit&gt;();</span>
<span class="nc" id="L2278">              int number = 0;</span>
<span class="nc bnc" id="L2279" title="All 2 branches missed.">              for (Match m : matchList) {</span>
<span class="nc bnc" id="L2280" title="All 2 branches missed.">                if (kwic.number != null) {</span>
<span class="nc bnc" id="L2281" title="All 2 branches missed.">                  if (number &gt;= (kwic.start + kwic.number)) {</span>
<span class="nc" id="L2282">                    break;</span>
                  }
                }
<span class="nc bnc" id="L2285" title="All 2 branches missed.">                if (number &gt;= kwic.start) {</span>
<span class="nc" id="L2286">                  int startPosition = m.startPosition;</span>
<span class="nc" id="L2287">                  int endPosition = m.endPosition - 1;</span>
<span class="nc" id="L2288">                  ArrayList&lt;MtasTreeHit&lt;String&gt;&gt; terms = mtasCodecInfo</span>
<span class="nc" id="L2289">                      .getPositionedTermsByPrefixesAndPositionRange(field,</span>
                          (docId - docBase), kwic.prefixes,
<span class="nc" id="L2291">                          Math.max(mDoc.minPosition, startPosition - kwic.left),</span>
<span class="nc" id="L2292">                          Math.min(mDoc.maxPosition, endPosition + kwic.right));</span>
                  // construct hit
<span class="nc" id="L2294">                  HashMap&lt;Integer, ArrayList&lt;String&gt;&gt; kwicListHits = new HashMap&lt;Integer, ArrayList&lt;String&gt;&gt;();</span>
<span class="nc" id="L2295">                  for (int position = Math.max(mDoc.minPosition,</span>
<span class="nc bnc" id="L2296" title="All 2 branches missed.">                      startPosition - kwic.left); position &lt;= Math.min(</span>
                          mDoc.maxPosition,
<span class="nc" id="L2298">                          endPosition + kwic.right); position++) {</span>
<span class="nc" id="L2299">                    kwicListHits.put(position, new ArrayList&lt;String&gt;());</span>
                  }
                  ArrayList&lt;String&gt; termList;
<span class="nc bnc" id="L2302" title="All 2 branches missed.">                  for (MtasTreeHit&lt;String&gt; term : terms) {</span>
<span class="nc" id="L2303">                    for (int position = Math.max((startPosition - kwic.left),</span>
<span class="nc bnc" id="L2304" title="All 2 branches missed.">                        term.startPosition); position &lt;= Math.min(</span>
                            (endPosition + kwic.right),
<span class="nc" id="L2306">                            term.endPosition); position++) {</span>
<span class="nc" id="L2307">                      termList = kwicListHits.get(position);</span>
<span class="nc" id="L2308">                      termList.add(term.data);</span>
                    }
<span class="nc" id="L2310">                  }</span>
<span class="nc" id="L2311">                  kwicItemList.add(new KwicHit(m, kwicListHits));</span>
                }
<span class="nc" id="L2313">                number++;</span>
<span class="nc" id="L2314">              }</span>
<span class="nc" id="L2315">              kwic.hits.put(docId, kwicItemList);</span>
            }
<span class="nc" id="L2317">          }</span>
<span class="nc bnc" id="L2318" title="All 2 branches missed.">        } else if (kwic.output.equals(ComponentKwic.KWIC_OUTPUT_TOKEN)) {</span>
<span class="nc bnc" id="L2319" title="All 2 branches missed.">          for (int docId : docList) {</span>
<span class="nc bnc" id="L2320" title="All 2 branches missed.">            if (matchData != null</span>
<span class="nc bnc" id="L2321" title="All 2 branches missed.">                &amp;&amp; (matchList = matchData.get(docId)) != null) {</span>
              // get unique id
<span class="nc" id="L2323">              Document doc = searcher.doc(docId,</span>
<span class="nc" id="L2324">                  new HashSet&lt;String&gt;(Arrays.asList(uniqueKeyField)));</span>
              // get other doc info
<span class="nc" id="L2326">              IndexableField indxfld = doc.getField(uniqueKeyField);</span>
<span class="nc bnc" id="L2327" title="All 2 branches missed.">              if (indxfld != null) {</span>
<span class="nc" id="L2328">                kwic.uniqueKey.put(docId, indxfld.stringValue());</span>
              }
<span class="nc" id="L2330">              kwic.subTotal.put(docId, matchList.size());</span>
<span class="nc" id="L2331">              IndexDoc mDoc = mtasCodecInfo.getDoc(field, (docId - docBase));</span>
<span class="nc bnc" id="L2332" title="All 2 branches missed.">              if (mDoc != null) {</span>
<span class="nc" id="L2333">                kwic.minPosition.put(docId, mDoc.minPosition);</span>
<span class="nc" id="L2334">                kwic.maxPosition.put(docId, mDoc.maxPosition);</span>
              }
<span class="nc" id="L2336">              ArrayList&lt;KwicToken&gt; kwicItemList = new ArrayList&lt;KwicToken&gt;();</span>
<span class="nc" id="L2337">              int number = 0;</span>
<span class="nc bnc" id="L2338" title="All 2 branches missed.">              for (Match m : matchList) {</span>
<span class="nc bnc" id="L2339" title="All 2 branches missed.">                if (kwic.number != null) {</span>
<span class="nc bnc" id="L2340" title="All 2 branches missed.">                  if (number &gt;= (kwic.start + kwic.number)) {</span>
<span class="nc" id="L2341">                    break;</span>
                  }
                }
<span class="nc bnc" id="L2344" title="All 2 branches missed.">                if (number &gt;= kwic.start) {</span>
<span class="nc" id="L2345">                  int startPosition = m.startPosition;</span>
<span class="nc" id="L2346">                  int endPosition = m.endPosition - 1;</span>
                  ArrayList&lt;MtasTokenString&gt; tokens;
<span class="nc" id="L2348">                  tokens = mtasCodecInfo.getPrefixFilteredObjectsByPositions(</span>
                      field, (docId - docBase), kwic.prefixes,
<span class="nc" id="L2350">                      Math.max(mDoc.minPosition, startPosition - kwic.left),</span>
<span class="nc" id="L2351">                      Math.min(mDoc.maxPosition, endPosition + kwic.right));</span>
<span class="nc" id="L2352">                  kwicItemList.add(new KwicToken(m, tokens));</span>
                }
<span class="nc" id="L2354">                number++;</span>
<span class="nc" id="L2355">              }</span>
<span class="nc" id="L2356">              kwic.tokens.put(docId, kwicItemList);</span>
            }
<span class="nc" id="L2358">          }</span>
        }
<span class="nc" id="L2360">      }</span>
    }
<span class="nc" id="L2362">  }</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,
      HashMap&lt;Integer, Integer&gt; positionsData,
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, Integer&gt;&gt; spansNumberData,
      HashMap&lt;String, TreeMap&lt;String, int[]&gt;&gt; facetData, Integer[] docSet)
      throws IOException {
<span class="nc bnc" id="L2390" title="All 2 branches missed.">    for (MtasFunctionParserFunction function : cf.baseFunctionParserFunctions[level]) {</span>
<span class="nc bnc" id="L2391" title="All 2 branches missed.">      if (function.needArgumentsNumber() &gt; cf.spanQueries.length) {</span>
<span class="nc" id="L2392">        throw new IOException(&quot;function &quot; + function + &quot; expects (at least) &quot;</span>
<span class="nc" id="L2393">            + function.needArgumentsNumber() + &quot; queries&quot;);</span>
      }
    }
<span class="nc" id="L2396">    TreeMap&lt;String, int[]&gt; list = facetData.get(cf.baseFields[level]);</span>
<span class="nc bnc" id="L2397" title="All 2 branches missed.">    if (dataCollector != null) {</span>
<span class="nc" id="L2398">      MtasDataCollector&lt;?, ?&gt; subDataCollector = null;</span>
<span class="nc" id="L2399">      dataCollector.initNewList(1);</span>
<span class="nc bnc" id="L2400" title="All 2 branches missed.">      if (cf.baseFunctionList[level] != null) {</span>
        SubComponentFunction[] tmpList;
<span class="nc bnc" id="L2402" title="All 2 branches missed.">        if (!cf.baseFunctionList[level].containsKey(dataCollector)) {</span>
<span class="nc" id="L2403">          tmpList = new SubComponentFunction[cf.baseFunctionParserFunctions[level].length];</span>
<span class="nc" id="L2404">          cf.baseFunctionList[level].put(dataCollector, tmpList);</span>
<span class="nc bnc" id="L2405" title="All 2 branches missed.">          for (int i = 0; i &lt; cf.baseFunctionParserFunctions[level].length; i++) {</span>
            try {
<span class="nc" id="L2407">              tmpList[i] = new SubComponentFunction(</span>
                  DataCollector.COLLECTOR_TYPE_LIST,
                  cf.baseFunctionKeys[level][i], cf.baseFunctionTypes[level][i],
<span class="nc" id="L2410">                  cf.baseFunctionParserFunctions[level][i], null, null, 0,</span>
<span class="nc" id="L2411">                  Integer.MAX_VALUE, null, null);</span>

<span class="nc" id="L2413">            } catch (ParseException e) {</span>
<span class="nc" id="L2414">              throw new IOException(e.getMessage());</span>
<span class="nc" id="L2415">            }</span>
          }
        } else {
<span class="nc" id="L2418">          tmpList = cf.baseFunctionList[level].get(dataCollector);</span>
        }
<span class="nc bnc" id="L2420" title="All 2 branches missed.">        for (SubComponentFunction function : tmpList) {</span>
<span class="nc" id="L2421">          function.dataCollector.initNewList(1);</span>
        }
      }
      // check type
<span class="nc" id="L2425">      if (dataCollector.getCollectorType()</span>
<span class="nc bnc" id="L2426" title="All 2 branches missed.">          .equals(DataCollector.COLLECTOR_TYPE_LIST)) {</span>
<span class="nc" id="L2427">        dataCollector.setWithTotal();</span>
        // only if documents and facets
<span class="nc bnc" id="L2429" title="All 4 branches missed.">        if (docSet.length &gt; 0 &amp;&amp; list.size() &gt; 0) {</span>
<span class="nc" id="L2430">          HashMap&lt;String, Integer[]&gt; docLists = new HashMap&lt;String, Integer[]&gt;();</span>
<span class="nc" id="L2431">          HashMap&lt;String, String&gt; groupedKeys = new HashMap&lt;String, String&gt;();</span>
<span class="nc" id="L2432">          boolean documentsInFacets = false;</span>
          // compute intersections
<span class="nc bnc" id="L2434" title="All 2 branches missed.">          for (Entry&lt;String, int[]&gt; entry : list.entrySet()) {</span>
            // fill grouped keys
<span class="nc bnc" id="L2436" title="All 2 branches missed.">            if (!groupedKeys.containsKey(entry.getKey())) {</span>
<span class="nc" id="L2437">              groupedKeys.put(entry.getKey(), groupedKeyName(entry.getKey(), cf.baseRangeSizes[level],</span>
                  cf.baseRangeBases[level]));
            }
            // intersect docSet with docList
<span class="nc" id="L2441">            Integer[] docList = intersectedDocList(entry.getValue(), docSet);</span>
<span class="nc bnc" id="L2442" title="All 2 branches missed.">            if (docList.length &gt; 0) {</span>
<span class="nc" id="L2443">              documentsInFacets = true;</span>
            }
            // update docLists
<span class="nc bnc" id="L2446" title="All 2 branches missed.">            if (docLists.containsKey(groupedKeys.get(entry.getKey()))) {</span>
<span class="nc" id="L2447">              docLists.put(groupedKeys.get(entry.getKey()),</span>
<span class="nc" id="L2448">                  mergeDocLists(docLists.get(groupedKeys.get(entry.getKey())), docList));</span>
            } else {
<span class="nc" id="L2450">              docLists.put(groupedKeys.get(entry.getKey()), docList);</span>
            }
<span class="nc" id="L2452">          }</span>
          // compute stats for each key
<span class="nc bnc" id="L2454" title="All 2 branches missed.">          if (documentsInFacets) {</span>
<span class="nc" id="L2455">            HashMap&lt;Integer, long[]&gt; args = computeArguments(spansNumberData,</span>
                cf.spanQueries, docSet);
<span class="nc bnc" id="L2457" title="All 2 branches missed.">            if (cf.baseDataTypes[level].equals(CodecUtil.DATA_TYPE_LONG)) {</span>
              // check functions
<span class="nc" id="L2459">              boolean applySumRule = false;</span>
<span class="nc bnc" id="L2460" title="All 2 branches missed.">              if (cf.baseStatsTypes[level].equals(CodecUtil.STATS_BASIC)</span>
<span class="nc bnc" id="L2461" 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="L2464">                applySumRule = true;</span>
<span class="nc bnc" id="L2465" title="All 2 branches missed.">                if (cf.baseFunctionList[level].get(dataCollector) != null) {</span>
                  for (SubComponentFunction function : cf.baseFunctionList[level]
<span class="nc bnc" id="L2467" title="All 2 branches missed.">                      .get(dataCollector)) {</span>
<span class="nc bnc" id="L2468" title="All 2 branches missed.">                    if (!function.statsType.equals(CodecUtil.STATS_BASIC)</span>
<span class="nc bnc" id="L2469" title="All 2 branches missed.">                        || !function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L2470" title="All 2 branches missed.">                        || function.parserFunction.needPositions()) {</span>
<span class="nc" id="L2471">                      applySumRule = false;</span>
<span class="nc" id="L2472">                      break;</span>
                    }
                  }
                }
              }
<span class="nc bnc" id="L2477" title="All 2 branches missed.">              if (applySumRule) {</span>
<span class="nc bnc" id="L2478" title="All 2 branches missed.">                for (String key : new LinkedHashSet&lt;String&gt;(</span>
<span class="nc" id="L2479">                    groupedKeys.values())) {</span>
<span class="nc bnc" id="L2480" title="All 2 branches missed.">                  if (docLists.get(key).length &gt; 0) {</span>
                    // initialise
<span class="nc" id="L2482">                    Integer[] subDocSet = docLists.get(key);</span>
<span class="nc" id="L2483">                    int length = cf.baseParsers[level].needArgumentsNumber();</span>
<span class="nc" id="L2484">                    long[] valueSum = new long[length];</span>
<span class="nc" id="L2485">                    long valuePositions = 0;</span>
                    // collect
<span class="nc bnc" id="L2487" title="All 2 branches missed.">                    if (subDocSet.length &gt; 0) {</span>
                      long[] tmpArgs;
<span class="nc bnc" id="L2489" title="All 2 branches missed.">                      for (int docId : subDocSet) {</span>
<span class="nc" id="L2490">                        tmpArgs = args.get(docId);</span>
<span class="nc bnc" id="L2491" title="All 2 branches missed.">                        if (positionsData != null</span>
<span class="nc bnc" id="L2492" title="All 2 branches missed.">                            &amp;&amp; positionsData.containsKey(docId)</span>
<span class="nc bnc" id="L2493" title="All 2 branches missed.">                            &amp;&amp; positionsData.get(docId) != null) {</span>
<span class="nc" id="L2494">                          valuePositions += positionsData.get(docId)</span>
<span class="nc" id="L2495">                              .longValue();</span>
                        }
<span class="nc bnc" id="L2497" title="All 2 branches missed.">                        if (tmpArgs != null) {</span>
<span class="nc bnc" id="L2498" title="All 2 branches missed.">                          for (int i = 0; i &lt; length; i++) {</span>
<span class="nc" id="L2499">                            valueSum[i] += tmpArgs[i];</span>
                          }
                        }
                      }
                      long value;
                      try {
<span class="nc" id="L2505">                        value = cf.baseParsers[level].getValueLong(valueSum,</span>
                            valuePositions);
<span class="nc" id="L2507">                        subDataCollector = dataCollector.add(key, value,</span>
                            subDocSet.length);
<span class="nc" id="L2509">                      } catch (IOException e) {</span>
<span class="nc" id="L2510">                        dataCollector.error(key, e.getMessage());</span>
<span class="nc" id="L2511">                        subDataCollector = null;</span>
<span class="nc" id="L2512">                      }</span>
<span class="nc bnc" id="L2513" title="All 2 branches missed.">                      if (cf.baseFunctionList[level] != null</span>
                          &amp;&amp; cf.baseFunctionList[level]
<span class="nc bnc" id="L2515" title="All 2 branches missed.">                              .containsKey(dataCollector)) {</span>
<span class="nc" id="L2516">                        SubComponentFunction[] functionList = cf.baseFunctionList[level]</span>
<span class="nc" id="L2517">                            .get(dataCollector);</span>
<span class="nc bnc" id="L2518" title="All 2 branches missed.">                        for (SubComponentFunction function : functionList) {</span>
<span class="nc" id="L2519">                          if (function.dataType</span>
<span class="nc bnc" id="L2520" title="All 2 branches missed.">                              .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                            try {
<span class="nc" id="L2522">                              long valueLong = function.parserFunction</span>
<span class="nc" id="L2523">                                  .getValueLong(valueSum, valuePositions);</span>
<span class="nc" id="L2524">                              function.dataCollector.add(key, valueLong,</span>
                                  subDocSet.length);
<span class="nc" id="L2526">                            } catch (IOException e) {</span>
<span class="nc" id="L2527">                              function.dataCollector.error(key, e.getMessage());</span>
<span class="nc" id="L2528">                            }</span>
<span class="nc" id="L2529">                          } else if (function.dataType</span>
<span class="nc bnc" id="L2530" title="All 2 branches missed.">                              .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
                            try {
<span class="nc" id="L2532">                              double valueDouble = function.parserFunction</span>
<span class="nc" id="L2533">                                  .getValueDouble(valueSum, valuePositions);</span>
<span class="nc" id="L2534">                              function.dataCollector.add(key, valueDouble,</span>
                                  subDocSet.length);
<span class="nc" id="L2536">                            } catch (IOException e) {</span>
<span class="nc" id="L2537">                              function.dataCollector.error(key, e.getMessage());</span>
<span class="nc" id="L2538">                            }</span>
                          }
                        }
                      }
<span class="nc bnc" id="L2542" title="All 2 branches missed.">                      if (subDataCollector != null) {</span>
<span class="nc" id="L2543">                        createFacetBase(cf, (level + 1), subDataCollector,</span>
                            positionsData, spansNumberData, facetData,
                            subDocSet);
                      }
                    }
                  }
<span class="nc" id="L2549">                }</span>
              } else {
<span class="nc bnc" id="L2551" title="All 2 branches missed.">                for (String key : new LinkedHashSet&lt;String&gt;(</span>
<span class="nc" id="L2552">                    groupedKeys.values())) {</span>
<span class="nc bnc" id="L2553" title="All 2 branches missed.">                  if (docLists.get(key).length &gt; 0) {</span>
                    // initialise
<span class="nc" id="L2555">                    Integer[] subDocSet = docLists.get(key);</span>
                    // collect
<span class="nc bnc" id="L2557" title="All 2 branches missed.">                    if (subDocSet.length &gt; 0) {</span>
<span class="nc" id="L2558">                      if (cf.baseDataTypes[level]</span>
<span class="nc bnc" id="L2559" title="All 2 branches missed.">                          .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                        // check for functions
<span class="nc" id="L2561">                        long[][] functionValuesLong = null;</span>
<span class="nc" id="L2562">                        double[][] functionValuesDouble = null;</span>
<span class="nc" id="L2563">                        int[] functionNumber = null;</span>
<span class="nc" id="L2564">                        SubComponentFunction[] functionList = null;</span>
<span class="nc bnc" id="L2565" title="All 2 branches missed.">                        if (cf.baseFunctionList[level] != null</span>
                            &amp;&amp; cf.baseFunctionList[level]
<span class="nc bnc" id="L2567" title="All 2 branches missed.">                                .containsKey(dataCollector)) {</span>
<span class="nc" id="L2568">                          functionList = cf.baseFunctionList[level]</span>
<span class="nc" id="L2569">                              .get(dataCollector);</span>
<span class="nc" id="L2570">                          functionValuesLong = new long[functionList.length][];</span>
<span class="nc" id="L2571">                          functionValuesDouble = new double[functionList.length][];</span>
<span class="nc" id="L2572">                          functionNumber = new int[functionList.length];</span>
<span class="nc bnc" id="L2573" title="All 2 branches missed.">                          for (int i = 0; i &lt; functionList.length; i++) {</span>
<span class="nc" id="L2574">                            functionValuesLong[i] = new long[subDocSet.length];</span>
<span class="nc" id="L2575">                            functionValuesDouble[i] = new double[subDocSet.length];</span>
                          }
                        }
                        // check main
<span class="nc" id="L2579">                        int number = 0;</span>
<span class="nc" id="L2580">                        Integer[] restrictedSubDocSet = new Integer[subDocSet.length];</span>
<span class="nc" id="L2581">                        long[] values = new long[subDocSet.length];</span>
<span class="nc bnc" id="L2582" title="All 2 branches missed.">                        for (int docId : subDocSet) {</span>
                          try {
<span class="nc" id="L2584">                            long[] tmpArgs = args.get(docId);</span>
<span class="nc bnc" id="L2585" title="All 2 branches missed.">                            int tmpPositions = (positionsData == null) ? 0</span>
<span class="nc" id="L2586">                                : positionsData.get(docId);</span>
<span class="nc" id="L2587">                            long value = cf.baseParsers[level]</span>
<span class="nc" id="L2588">                                .getValueLong(tmpArgs, tmpPositions);</span>
<span class="nc bnc" id="L2589" title="All 2 branches missed.">                            if ((cf.baseMinimumLongs[level] == null</span>
<span class="nc bnc" id="L2590" title="All 4 branches missed.">                                || value &gt;= cf.baseMinimumLongs[level])</span>
                                &amp;&amp; (cf.baseMaximumLongs[level] == null
<span class="nc bnc" id="L2592" title="All 2 branches missed.">                                    || value &lt;= cf.baseMaximumLongs[level])) {</span>
<span class="nc" id="L2593">                              values[number] = value;</span>
<span class="nc" id="L2594">                              restrictedSubDocSet[number] = docId;</span>
<span class="nc" id="L2595">                              number++;</span>
<span class="nc bnc" id="L2596" title="All 2 branches missed.">                              if (functionList != null) {</span>
<span class="nc bnc" id="L2597" title="All 2 branches missed.">                                for (int i = 0; i &lt; functionList.length; i++) {</span>
<span class="nc" id="L2598">                                  SubComponentFunction function = functionList[i];</span>
<span class="nc" id="L2599">                                  if (function.dataType</span>
<span class="nc bnc" id="L2600" title="All 2 branches missed.">                                      .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
                                    try {
<span class="nc" id="L2602">                                      functionValuesLong[i][functionNumber[i]] = function.parserFunction</span>
<span class="nc" id="L2603">                                          .getValueLong(tmpArgs, tmpPositions);</span>
<span class="nc" id="L2604">                                      functionNumber[i]++;</span>
<span class="nc" id="L2605">                                    } catch (IOException e) {</span>
<span class="nc" id="L2606">                                      function.dataCollector.error(key,</span>
<span class="nc" id="L2607">                                          e.getMessage());</span>
<span class="nc" id="L2608">                                    }</span>
<span class="nc" id="L2609">                                  } else if (function.dataType</span>
<span class="nc bnc" id="L2610" title="All 2 branches missed.">                                      .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
                                    try {
<span class="nc" id="L2612">                                      functionValuesDouble[i][functionNumber[i]] = function.parserFunction</span>
<span class="nc" id="L2613">                                          .getValueDouble(tmpArgs,</span>
                                              tmpPositions);
<span class="nc" id="L2615">                                      functionNumber[i]++;</span>
<span class="nc" id="L2616">                                    } catch (IOException e) {</span>
<span class="nc" id="L2617">                                      function.dataCollector.error(key,</span>
<span class="nc" id="L2618">                                          e.getMessage());</span>
<span class="nc" id="L2619">                                    }</span>
                                  }
                                }
                              }
                            }
<span class="nc" id="L2624">                          } catch (IOException e) {</span>
<span class="nc" id="L2625">                            dataCollector.error(key, e.getMessage());</span>
<span class="nc" id="L2626">                          }</span>
                        }
<span class="nc bnc" id="L2628" title="All 2 branches missed.">                        if (number &gt; 0) {</span>
<span class="nc" id="L2629">                          subDataCollector = dataCollector.add(key, values,</span>
                              number);
<span class="nc bnc" id="L2631" title="All 2 branches missed.">                          if (cf.baseFunctionList[level] != null</span>
                              &amp;&amp; cf.baseFunctionList[level]
<span class="nc bnc" id="L2633" title="All 2 branches missed.">                                  .containsKey(dataCollector)) {</span>
<span class="nc bnc" id="L2634" title="All 2 branches missed.">                            for (int i = 0; i &lt; functionList.length; i++) {</span>
<span class="nc" id="L2635">                              SubComponentFunction function = functionList[i];</span>
<span class="nc" id="L2636">                              if (function.dataType</span>
<span class="nc bnc" id="L2637" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L2638">                                function.dataCollector.add(key,</span>
                                    functionValuesLong[i], functionNumber[i]);
<span class="nc" id="L2640">                              } else if (function.dataType</span>
<span class="nc bnc" id="L2641" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L2642">                                function.dataCollector.add(key,</span>
                                    functionValuesDouble[i], functionNumber[i]);
                              }
                            }
                          }
<span class="nc bnc" id="L2647" title="All 2 branches missed.">                          if (subDataCollector != null) {</span>
<span class="nc" id="L2648">                            createFacetBase(cf, (level + 1), subDataCollector,</span>
                                positionsData, spansNumberData, facetData,
<span class="nc" id="L2650">                                Arrays.copyOfRange(restrictedSubDocSet, 0,</span>
                                    number));
                          }
                        }
                      }
                    }
                  }
<span class="nc" id="L2657">                }</span>
              }
<span class="nc" id="L2659">            } else {</span>
<span class="nc" id="L2660">              throw new IOException(</span>
                  &quot;unexpected dataType &quot; + cf.baseDataTypes[level]);
            }
          }
<span class="nc" id="L2664">        }</span>
      } else {
<span class="nc" id="L2666">        throw new IOException(</span>
<span class="nc" id="L2667">            &quot;unexpected type &quot; + dataCollector.getCollectorType());</span>
      }
<span class="nc" id="L2669">      dataCollector.closeNewList();</span>
<span class="nc bnc" id="L2670" title="All 2 branches missed.">      if (cf.baseFunctionList[level] != null</span>
<span class="nc bnc" id="L2671" title="All 2 branches missed.">          &amp;&amp; cf.baseFunctionList[level].containsKey(dataCollector)) {</span>
<span class="nc" id="L2672">        SubComponentFunction[] tmpList = cf.baseFunctionList[level]</span>
<span class="nc" id="L2673">            .get(dataCollector);</span>
<span class="nc bnc" id="L2674" title="All 2 branches missed.">        for (SubComponentFunction function : tmpList) {</span>
<span class="nc" id="L2675">          function.dataCollector.closeNewList();</span>
        }
      }
    }

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

  private static String groupedKeyName(String key, Double baseRangeSize,
      Double baseRangeBase) {
<span class="nc bnc" id="L2684" title="All 4 branches missed.">    if (baseRangeSize == null || baseRangeSize &lt;= 0) {</span>
<span class="nc" id="L2685">      return key;</span>
    } else {
      Double doubleKey;
      Double doubleBase;
      Double doubleNumber;
      Double doubleStart;
      Double doubleEnd;
      try {
<span class="nc" id="L2693">        doubleKey = Double.parseDouble(key);</span>
<span class="nc bnc" id="L2694" title="All 2 branches missed.">        doubleBase = baseRangeBase != null ? baseRangeBase : 0;</span>
<span class="nc" id="L2695">        doubleNumber = Math.floor((doubleKey - doubleBase) / baseRangeSize);</span>
<span class="nc" id="L2696">        doubleStart = doubleBase + doubleNumber * baseRangeSize;</span>
<span class="nc" id="L2697">        doubleEnd = doubleStart + baseRangeSize;</span>
<span class="nc" id="L2698">      } catch (NumberFormatException e) {</span>
<span class="nc" id="L2699">        return key;</span>
<span class="nc" id="L2700">      }</span>
      // integer
<span class="nc bnc" id="L2702" title="All 2 branches missed.">      if (Math.floor(baseRangeSize) == baseRangeSize</span>
<span class="nc bnc" id="L2703" title="All 2 branches missed.">          &amp;&amp; Math.floor(doubleBase) == doubleBase) {</span>
        try {
<span class="nc bnc" id="L2705" title="All 2 branches missed.">          if (baseRangeSize &gt; 1) {</span>
<span class="nc" id="L2706">            return String.format(&quot;%.0f&quot;, doubleStart) + &quot;-&quot;</span>
<span class="nc" id="L2707">                + String.format(&quot;%.0f&quot;, doubleEnd - 1);</span>
          } else {
<span class="nc" id="L2709">            return String.format(&quot;%.0f&quot;, doubleStart);</span>
          }
<span class="nc" id="L2711">        } catch (NumberFormatException e) {</span>
<span class="nc" id="L2712">          return key;</span>
        }
      } else {
<span class="nc" id="L2715">        return &quot;[&quot; + doubleStart + &quot;,&quot; + doubleEnd + &quot;)&quot;;</span>
      }
    }
  }

  private static Integer[] mergeDocLists(Integer[] a, Integer[] b) {
<span class="nc" id="L2721">    Integer[] answer = new Integer[a.length + b.length];</span>
<span class="nc" id="L2722">    int i = 0;</span>
<span class="nc" id="L2723">    int j = 0;</span>
<span class="nc" id="L2724">    int k = 0;</span>
    Integer tmp;
<span class="nc bnc" id="L2726" title="All 4 branches missed.">    while (i &lt; a.length &amp;&amp; j &lt; b.length) {</span>
<span class="nc bnc" id="L2727" title="All 2 branches missed.">      tmp = a[i] &lt; b[j] ? a[i++] : b[j++];</span>
<span class="nc bnc" id="L2728" title="All 4 branches missed.">      for (; i &lt; a.length &amp;&amp; a[i].equals(tmp); i++)</span>
        ;
<span class="nc bnc" id="L2730" title="All 4 branches missed.">      for (; j &lt; b.length &amp;&amp; b[j].equals(tmp); j++)</span>
        ;
<span class="nc" id="L2732">      answer[k++] = tmp;</span>
    }
<span class="nc bnc" id="L2734" title="All 2 branches missed.">    while (i &lt; a.length) {</span>
<span class="nc" id="L2735">      tmp = a[i++];</span>
<span class="nc bnc" id="L2736" title="All 4 branches missed.">      for (; i &lt; a.length &amp;&amp; a[i].equals(tmp); i++)</span>
        ;
<span class="nc" id="L2738">      answer[k++] = tmp;</span>
    }
<span class="nc bnc" id="L2740" title="All 2 branches missed.">    while (j &lt; b.length) {</span>
<span class="nc" id="L2741">      tmp = b[j++];</span>
<span class="nc bnc" id="L2742" title="All 4 branches missed.">      for (; j &lt; b.length &amp;&amp; b[j].equals(tmp); j++)</span>
        ;
<span class="nc" id="L2744">      answer[k++] = tmp;</span>
    }
<span class="nc" id="L2746">    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
   * @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 createFacet(List&lt;ComponentFacet&gt; facetList,
      HashMap&lt;Integer, Integer&gt; positionsData,
      HashMap&lt;MtasSpanQuery, HashMap&lt;Integer, Integer&gt;&gt; spansNumberData,
      HashMap&lt;String, TreeMap&lt;String, int[]&gt;&gt; facetData, List&lt;Integer&gt; docSet,
      String field, int docBase, String uniqueKeyField, CodecInfo mtasCodecInfo,
      IndexSearcher searcher) throws IOException {

<span class="nc bnc" id="L2782" title="All 2 branches missed.">    if (facetList != null) {</span>
<span class="nc bnc" id="L2783" title="All 2 branches missed.">      for (ComponentFacet cf : facetList) {</span>
<span class="nc bnc" id="L2784" title="All 2 branches missed.">        if (cf.baseFields.length &gt; 0) {</span>
<span class="nc" id="L2785">          createFacetBase(cf, 0, cf.dataCollector, positionsData,</span>
              spansNumberData, facetData,
<span class="nc" id="L2787">              docSet.toArray(new Integer[docSet.size()]));</span>
        }
<span class="nc" id="L2789">      }</span>
    }
<span class="nc" id="L2791">  }</span>

  /**
   * Creates the termvector full.
   *
   * @param termVectorList
   *          the term vector list
   * @param positionsData
   *          the positions data
   * @param docSet
   *          the doc set
   * @param field
   *          the field
   * @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,
      HashMap&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet,
      String field, Terms t, LeafReader r, LeafReaderContext lrc)
      throws IOException {
<span class="pc bpc" id="L2818" title="1 of 2 branches missed.">    if (t != null) {</span>
      BytesRef term;
      TermsEnum termsEnum;
<span class="fc" id="L2821">      PostingsEnum postingsEnum = null;</span>
<span class="fc" id="L2822">      String segmentName = &quot;segment&quot; + lrc.ord;</span>
<span class="fc" id="L2823">      int segmentNumber = lrc.parent.leaves().size();</span>
      // loop over termvectors
<span class="fc bfc" id="L2825" title="All 2 branches covered.">      for (ComponentTermVector termVector : termVectorList) {</span>
<span class="pc bpc" id="L2826" title="1 of 4 branches missed.">        if (termVector.full || termVector.list != null) {</span>
<span class="pc bpc" id="L2827" title="1 of 2 branches missed.">          if (termVector.full) {</span>
<span class="fc" id="L2828">            termVector.subComponentFunction.dataCollector.setWithTotal();</span>
          }
          List&lt;CompiledAutomaton&gt; listAutomata;
          HashMap&lt;String, Automaton&gt; automatonMap;
<span class="pc bpc" id="L2832" title="1 of 2 branches missed.">          if (termVector.list == null) {</span>
<span class="fc" id="L2833">            automatonMap = null;</span>
<span class="fc" id="L2834">            listAutomata = new ArrayList&lt;CompiledAutomaton&gt;();</span>
            CompiledAutomaton compiledAutomaton;
            Automaton automaton;
<span class="pc bpc" id="L2837" title="3 of 4 branches missed.">            if ((termVector.regexp == null) || (termVector.regexp.isEmpty())) {</span>
<span class="fc" id="L2838">              RegExp re = new RegExp(</span>
                  termVector.prefix + MtasToken.DELIMITER + &quot;.*&quot;);
<span class="fc" id="L2840">              automaton = re.toAutomaton();</span>
<span class="fc" id="L2841">            } else {</span>
<span class="nc" id="L2842">              RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
                  + termVector.regexp + &quot;\u0000*&quot;);
<span class="nc" id="L2844">              automaton = re.toAutomaton();</span>
            }
<span class="fc" id="L2846">            compiledAutomaton = new CompiledAutomaton(automaton);</span>
<span class="fc" id="L2847">            listAutomata.add(compiledAutomaton);</span>
<span class="fc" id="L2848">          } else {</span>
<span class="nc bnc" id="L2849" title="All 2 branches missed.">            automatonMap = MtasToken.createAutomatonMap(termVector.prefix,</span>
                new ArrayList&lt;String&gt;(termVector.list),
<span class="nc" id="L2851">                termVector.listRegexp ? false : true);</span>
<span class="nc" id="L2852">            listAutomata = MtasToken.createAutomata(termVector.prefix,</span>
                termVector.regexp, automatonMap);
          }
<span class="fc" id="L2855">          List&lt;ByteRunAutomaton&gt; ignoreByteRunAutomatonList = null;</span>
<span class="pc bpc" id="L2856" title="1 of 2 branches missed.">          if ((termVector.ignoreRegexp != null)</span>
<span class="pc bpc" id="L2857" title="1 of 2 branches missed.">              &amp;&amp; (!termVector.ignoreRegexp.isEmpty())) {</span>
<span class="fc" id="L2858">            ignoreByteRunAutomatonList = new ArrayList&lt;ByteRunAutomaton&gt;();</span>
<span class="fc" id="L2859">            RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
                + termVector.ignoreRegexp + &quot;\u0000*&quot;);
<span class="fc" id="L2861">            ignoreByteRunAutomatonList</span>
<span class="fc" id="L2862">                .add(new ByteRunAutomaton(re.toAutomaton()));</span>
          }
<span class="pc bpc" id="L2864" title="1 of 2 branches missed.">          if (termVector.ignoreList != null) {</span>
<span class="nc bnc" id="L2865" title="All 2 branches missed.">            if (ignoreByteRunAutomatonList == null) {</span>
<span class="nc" id="L2866">              ignoreByteRunAutomatonList = new ArrayList&lt;ByteRunAutomaton&gt;();</span>
            }
<span class="nc bnc" id="L2868" title="All 2 branches missed.">            HashMap&lt;String, Automaton&gt; list = MtasToken.createAutomatonMap(</span>
                termVector.prefix, new ArrayList&lt;String&gt;(termVector.ignoreList),
<span class="nc" id="L2870">                termVector.ignoreListRegexp ? false : true);</span>
<span class="nc bnc" id="L2871" title="All 2 branches missed.">            for (Automaton automaton : list.values()) {</span>
<span class="nc" id="L2872">              ignoreByteRunAutomatonList.add(new ByteRunAutomaton(automaton));</span>
<span class="nc" id="L2873">            }</span>
          }

<span class="fc bfc" id="L2876" title="All 2 branches covered.">          for (CompiledAutomaton compiledAutomaton : listAutomata) {</span>
<span class="fc" id="L2877">            if (!compiledAutomaton.type</span>
<span class="pc bpc" id="L2878" title="1 of 2 branches missed.">                .equals(CompiledAutomaton.AUTOMATON_TYPE.NORMAL)) {</span>
<span class="nc" id="L2879">              if (compiledAutomaton.type</span>
<span class="nc bnc" id="L2880" title="All 2 branches missed.">                  .equals(CompiledAutomaton.AUTOMATON_TYPE.NONE)) {</span>
                // do nothing
              } else {
<span class="nc" id="L2883">                throw new IOException(</span>
                    &quot;compiledAutomaton is &quot; + compiledAutomaton.type);
              }
            } else {
<span class="fc" id="L2887">              termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="fc" id="L2888">              int initSize = Math.min((int) t.size(), 1000);</span>
<span class="fc" id="L2889">              termVector.subComponentFunction.dataCollector.initNewList(</span>
                  initSize, segmentName, segmentNumber, termVector.boundary);
<span class="fc" id="L2891">              boolean doBasic = termVector.subComponentFunction.dataCollector</span>
<span class="fc" id="L2892">                  .getStatsType().equals(CodecUtil.STATS_BASIC);</span>
<span class="pc bpc" id="L2893" title="1 of 2 branches missed.">              if (termVector.functions != null) {</span>
<span class="pc bpc" id="L2894" title="1 of 2 branches missed.">                for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2895">                  function.dataCollector.initNewList(initSize);</span>
<span class="nc bnc" id="L2896" title="All 4 branches missed.">                  doBasic = doBasic ? (function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L2897" title="All 2 branches missed.">                      &amp;&amp; !function.parserFunction.needPositions()</span>
<span class="nc" id="L2898">                      &amp;&amp; function.dataCollector.getStatsType()</span>
<span class="nc bnc" id="L2899" title="All 2 branches missed.">                          .equals(CodecUtil.STATS_BASIC))</span>
                      : doBasic;
<span class="nc" id="L2901">                }</span>
              }
              // only if documents
<span class="pc bpc" id="L2904" title="1 of 2 branches missed.">              if (docSet.size() &gt; 0) {</span>
                int termDocId;
                boolean acceptedTerm;
                String key;
                // loop over terms
<span class="fc bfc" id="L2909" title="All 2 branches covered.">                while ((term = termsEnum.next()) != null) {</span>
<span class="pc bpc" id="L2910" title="1 of 2 branches missed.">                  if (validateTermWithStartValue(term, termVector)) {</span>
<span class="fc" id="L2911">                    termDocId = -1;</span>
<span class="fc" id="L2912">                    acceptedTerm = true;</span>
<span class="pc bpc" id="L2913" title="1 of 2 branches missed.">                    if (ignoreByteRunAutomatonList != null) {</span>
<span class="fc bfc" id="L2914" title="All 2 branches covered.">                      for (ByteRunAutomaton ignoreByteRunAutomaton : ignoreByteRunAutomatonList) {</span>
<span class="pc bpc" id="L2915" title="1 of 2 branches missed.">                        if (ignoreByteRunAutomaton.run(term.bytes, term.offset,</span>
                            term.length)) {
<span class="nc" id="L2917">                          acceptedTerm = false;</span>
<span class="nc" id="L2918">                          break;</span>
                        }
<span class="fc" id="L2920">                      }</span>
                    }
<span class="pc bpc" id="L2922" title="1 of 2 branches missed.">                    if (acceptedTerm) {</span>
<span class="pc bpc" id="L2923" title="1 of 2 branches missed.">                      if (doBasic) {</span>
                        // compute numbers;
<span class="fc" id="L2925">                        TermvectorNumberBasic numberBasic = computeTermvectorNumberBasic(</span>
                            docSet, termDocId, termsEnum, r, lrc, postingsEnum);
                        // register
<span class="fc bfc" id="L2928" title="All 2 branches covered.">                        if (numberBasic.docNumber &gt; 0) {</span>
<span class="fc" id="L2929">                          long valueLong = 0;</span>
<span class="fc" id="L2930">                          key = MtasToken.getPostfixFromValue(term);</span>
                          try {
<span class="fc" id="L2932">                            valueLong = termVector.subComponentFunction.parserFunction</span>
<span class="fc" id="L2933">                                .getValueLong(numberBasic.valueSum, 1);</span>
<span class="nc" id="L2934">                          } catch (IOException e) {</span>
<span class="nc" id="L2935">                            termVector.subComponentFunction.dataCollector.error(</span>
<span class="nc" id="L2936">                                MtasToken.getPostfixFromValue(term),</span>
<span class="nc" id="L2937">                                e.getMessage());</span>
<span class="fc" id="L2938">                          }</span>
<span class="fc" id="L2939">                          termVector.subComponentFunction.dataCollector.add(key,</span>
                              valueLong, numberBasic.docNumber);
<span class="pc bpc" id="L2941" title="1 of 2 branches missed.">                          if (termVector.functions != null) {</span>
<span class="pc bpc" id="L2942" title="1 of 2 branches missed.">                            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2943">                              if (function.dataType</span>
<span class="nc bnc" id="L2944" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L2945">                                long valueFunction = function.parserFunction</span>
<span class="nc" id="L2946">                                    .getValueLong(numberBasic.valueSum, 0);</span>
<span class="nc" id="L2947">                                function.dataCollector.add(key, valueFunction,</span>
                                    numberBasic.docNumber);
<span class="nc" id="L2949">                              } else if (function.dataType</span>
<span class="nc bnc" id="L2950" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L2951">                                double valueFunction = function.parserFunction</span>
<span class="nc" id="L2952">                                    .getValueDouble(numberBasic.valueSum, 0);</span>
<span class="nc" id="L2953">                                function.dataCollector.add(key, valueFunction,</span>
                                    numberBasic.docNumber);
                              }
<span class="nc" id="L2956">                            }</span>
                          }
                        }
<span class="fc" id="L2959">                      } else {</span>
<span class="nc" id="L2960">                        TermvectorNumberFull numberFull = computeTermvectorNumberFull(</span>
                            docSet, termDocId, termsEnum, r, lrc, postingsEnum,
                            positionsData);
<span class="nc bnc" id="L2963" title="All 2 branches missed.">                        if (numberFull.docNumber &gt; 0) {</span>
<span class="nc" id="L2964">                          long[] valuesLong = new long[numberFull.docNumber];</span>
<span class="nc" id="L2965">                          key = MtasToken.getPostfixFromValue(term);</span>
<span class="nc bnc" id="L2966" title="All 2 branches missed.">                          for (int i = 0; i &lt; numberFull.docNumber; i++) {</span>
                            try {
<span class="nc" id="L2968">                              valuesLong[i] = termVector.subComponentFunction.parserFunction</span>
<span class="nc" id="L2969">                                  .getValueLong(</span>
                                      new long[] { numberFull.args[i] },
                                      numberFull.positions[i]);
<span class="nc" id="L2972">                            } catch (IOException e) {</span>
<span class="nc" id="L2973">                              termVector.subComponentFunction.dataCollector</span>
<span class="nc" id="L2974">                                  .error(key, e.getMessage());</span>
<span class="nc" id="L2975">                            }</span>
                          }
<span class="nc" id="L2977">                          termVector.subComponentFunction.dataCollector.add(key,</span>
                              valuesLong, valuesLong.length);
<span class="nc bnc" id="L2979" title="All 2 branches missed.">                          if (termVector.functions != null) {</span>
<span class="nc bnc" id="L2980" title="All 2 branches missed.">                            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L2981">                              if (function.dataType</span>
<span class="nc bnc" id="L2982" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L2983">                                valuesLong = new long[numberFull.docNumber];</span>
<span class="nc bnc" id="L2984" title="All 2 branches missed.">                                for (int i = 0; i &lt; numberFull.docNumber; i++) {</span>
                                  try {
<span class="nc" id="L2986">                                    valuesLong[i] = function.parserFunction</span>
<span class="nc" id="L2987">                                        .getValueLong(</span>
                                            new long[] { numberFull.args[i] },
                                            numberFull.positions[i]);
<span class="nc" id="L2990">                                  } catch (IOException e) {</span>
<span class="nc" id="L2991">                                    function.dataCollector.error(key,</span>
<span class="nc" id="L2992">                                        e.getMessage());</span>
<span class="nc" id="L2993">                                  }</span>
                                }
<span class="nc" id="L2995">                                function.dataCollector.add(key, valuesLong,</span>
                                    valuesLong.length);
<span class="nc" id="L2997">                              } else if (function.dataType</span>
<span class="nc bnc" id="L2998" title="All 2 branches missed.">                                  .equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L2999">                                double[] valuesDouble = new double[numberFull.docNumber];</span>
<span class="nc bnc" id="L3000" title="All 2 branches missed.">                                for (int i = 0; i &lt; numberFull.docNumber; i++) {</span>
                                  try {
<span class="nc" id="L3002">                                    valuesDouble[i] = function.parserFunction</span>
<span class="nc" id="L3003">                                        .getValueDouble(</span>
                                            new long[] { numberFull.args[i] },
                                            numberFull.positions[i]);
<span class="nc" id="L3006">                                  } catch (IOException e) {</span>
<span class="nc" id="L3007">                                    function.dataCollector.error(key,</span>
<span class="nc" id="L3008">                                        e.getMessage());</span>
<span class="nc" id="L3009">                                  }</span>
                                }
<span class="nc" id="L3011">                                function.dataCollector.add(key, valuesDouble,</span>
                                    valuesDouble.length);
                              }
<span class="nc" id="L3014">                            }</span>
                          }
                        }

<span class="nc" id="L3018">                      }</span>
                    }
                  }
                }
              }
<span class="fc" id="L3023">              termVector.subComponentFunction.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L3024" title="1 of 2 branches missed.">              if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3025" title="1 of 2 branches missed.">                for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3026">                  function.dataCollector.closeNewList();</span>
<span class="nc" id="L3027">                }</span>
              }
            }
<span class="fc" id="L3030">          }</span>
        }
<span class="fc" id="L3032">      }</span>
    }
<span class="fc" id="L3034">  }</span>

  /**
   * Creates the termvector first round.
   *
   * @param termVectorList
   *          the term vector list
   * @param positionsData
   *          the positions data
   * @param docSet
   *          the doc set
   * @param field
   *          the field
   * @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,
      HashMap&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet,
      String field, Terms t, LeafReader r, LeafReaderContext lrc)
      throws IOException {
<span class="pc bpc" id="L3061" title="1 of 2 branches missed.">    if (t != null) {</span>
      BytesRef term;
      TermsEnum termsEnum;
<span class="fc" id="L3064">      PostingsEnum postingsEnum = null;</span>
<span class="fc" id="L3065">      String segmentName = &quot;segment&quot; + lrc.ord;</span>
<span class="fc" id="L3066">      String[] mutableKey = new String[1];</span>
<span class="fc" id="L3067">      int segmentNumber = lrc.parent.leaves().size();</span>
      // loop over termvectors
<span class="fc bfc" id="L3069" title="All 2 branches covered.">      for (ComponentTermVector termVector : termVectorList) {</span>
        CompiledAutomaton compiledAutomaton;
<span class="pc bpc" id="L3071" title="3 of 4 branches missed.">        if ((termVector.regexp == null) || (termVector.regexp.isEmpty())) {</span>
<span class="fc" id="L3072">          RegExp re = new RegExp(</span>
              termVector.prefix + MtasToken.DELIMITER + &quot;.*&quot;);
<span class="fc" id="L3074">          compiledAutomaton = new CompiledAutomaton(re.toAutomaton());</span>
<span class="fc" id="L3075">        } else {</span>
<span class="nc" id="L3076">          RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
              + termVector.regexp + &quot;\u0000*&quot;);
<span class="nc" id="L3078">          compiledAutomaton = new CompiledAutomaton(re.toAutomaton());</span>
        }
<span class="fc" id="L3080">        List&lt;ByteRunAutomaton&gt; ignoreByteRunAutomatonList = null;</span>
<span class="pc bpc" id="L3081" title="1 of 2 branches missed.">        if ((termVector.ignoreRegexp != null)</span>
<span class="pc bpc" id="L3082" title="1 of 2 branches missed.">            &amp;&amp; (!termVector.ignoreRegexp.isEmpty())) {</span>
<span class="fc" id="L3083">          ignoreByteRunAutomatonList = new ArrayList&lt;ByteRunAutomaton&gt;();</span>
<span class="fc" id="L3084">          RegExp re = new RegExp(termVector.prefix + MtasToken.DELIMITER</span>
              + termVector.ignoreRegexp + &quot;\u0000*&quot;);
<span class="fc" id="L3086">          ignoreByteRunAutomatonList</span>
<span class="fc" id="L3087">              .add(new ByteRunAutomaton(re.toAutomaton()));</span>
        }
<span class="pc bpc" id="L3089" title="1 of 2 branches missed.">        if (termVector.ignoreList != null) {</span>
<span class="nc bnc" id="L3090" title="All 2 branches missed.">          if (ignoreByteRunAutomatonList == null) {</span>
<span class="nc" id="L3091">            ignoreByteRunAutomatonList = new ArrayList&lt;ByteRunAutomaton&gt;();</span>
          }
<span class="nc bnc" id="L3093" title="All 2 branches missed.">          HashMap&lt;String, Automaton&gt; list = MtasToken.createAutomatonMap(</span>
              termVector.prefix, new ArrayList&lt;String&gt;(termVector.ignoreList),
<span class="nc" id="L3095">              termVector.ignoreListRegexp ? false : true);</span>
<span class="nc bnc" id="L3096" title="All 2 branches missed.">          for (Automaton automaton : list.values()) {</span>
<span class="nc" id="L3097">            ignoreByteRunAutomatonList.add(new ByteRunAutomaton(automaton));</span>
<span class="nc" id="L3098">          }</span>
        }
<span class="pc bpc" id="L3100" title="1 of 4 branches missed.">        if (!termVector.full &amp;&amp; termVector.list == null) {</span>
<span class="fc" id="L3101">          termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="fc" id="L3102">          int initSize = Math.min((int) t.size(), 1000);</span>
<span class="fc" id="L3103">          termVector.subComponentFunction.dataCollector.initNewList(initSize,</span>
              segmentName, segmentNumber, termVector.boundary);
<span class="pc bpc" id="L3105" title="1 of 2 branches missed.">          if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3106" title="1 of 2 branches missed.">            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3107">              function.dataCollector.initNewList(initSize);</span>
<span class="nc" id="L3108">            }</span>
          }
          // only if documents
<span class="pc bpc" id="L3111" title="1 of 2 branches missed.">          if (docSet.size() &gt; 0) {</span>
            int termDocId;
<span class="fc" id="L3113">            int termNumberMaximum = termVector.number;</span>
<span class="fc" id="L3114">            HashMap&lt;BytesRef, RegisterStatus&gt; computeFullList = new HashMap&lt;BytesRef, RegisterStatus&gt;();</span>
            RegisterStatus registerStatus;
            // basic, don't need full values
<span class="fc" id="L3117">            if (termVector.subComponentFunction.sortType</span>
<span class="pc bpc" id="L3118" title="1 of 2 branches missed.">                .equals(CodecUtil.SORT_TERM)</span>
                || termVector.subComponentFunction.sortType
<span class="pc bpc" id="L3120" title="1 of 2 branches missed.">                    .equals(CodecUtil.STATS_TYPE_SUM)</span>
                || termVector.subComponentFunction.sortType
<span class="nc bnc" id="L3122" title="All 2 branches missed.">                    .equals(CodecUtil.STATS_TYPE_N)) {</span>
<span class="fc" id="L3123">              int termCounter = 0;</span>

<span class="fc" id="L3125">              boolean continueAfterPreliminaryCheck, preliminaryCheck = false;</span>
<span class="pc bpc" id="L3126" title="1 of 4 branches missed.">              if (r.getLiveDocs() == null &amp;&amp; (docSet.size() != r.numDocs())) {</span>
<span class="nc" id="L3127">                preliminaryCheck = true;</span>
              }
              // loop over terms
              boolean acceptedTerm;
<span class="fc bfc" id="L3131" title="All 2 branches covered.">              while ((term = termsEnum.next()) != null) {</span>
<span class="pc bpc" id="L3132" title="1 of 2 branches missed.">                if (validateTermWithStartValue(term, termVector)) {</span>
<span class="fc" id="L3133">                  termDocId = -1;</span>
<span class="fc" id="L3134">                  acceptedTerm = true;</span>
<span class="pc bpc" id="L3135" title="1 of 2 branches missed.">                  if (ignoreByteRunAutomatonList != null) {</span>
<span class="fc bfc" id="L3136" title="All 2 branches covered.">                    for (ByteRunAutomaton ignoreByteRunAutomaton : ignoreByteRunAutomatonList) {</span>
<span class="pc bpc" id="L3137" title="1 of 2 branches missed.">                      if (ignoreByteRunAutomaton.run(term.bytes, term.offset,</span>
                          term.length)) {
<span class="nc" id="L3139">                        acceptedTerm = false;</span>
<span class="nc" id="L3140">                        break;</span>
                      }
<span class="fc" id="L3142">                    }</span>
                  }
<span class="pc bpc" id="L3144" title="1 of 2 branches missed.">                  if (acceptedTerm) {</span>
<span class="fc" id="L3145">                    continueAfterPreliminaryCheck = true;</span>
<span class="fc" id="L3146">                    mutableKey[0] = null;</span>
<span class="pc bpc" id="L3147" title="1 of 2 branches missed.">                    if (preliminaryCheck) {</span>
                      try {
<span class="nc" id="L3149">                        TermvectorNumberBasic preliminaryNumberBasic = computeTermvectorNumberBasic(</span>
                            termsEnum, r);
<span class="nc bnc" id="L3151" title="All 2 branches missed.">                        if (preliminaryNumberBasic.docNumber &gt; 0) {</span>
<span class="nc" id="L3152">                          continueAfterPreliminaryCheck = preliminaryRegisterValue(</span>
                              term, termVector, preliminaryNumberBasic,
<span class="nc" id="L3154">                              termNumberMaximum, segmentNumber, mutableKey);</span>
                        } else {
<span class="nc" id="L3156">                          continueAfterPreliminaryCheck = false;</span>
                        }
<span class="nc" id="L3158">                      } catch (IOException e) {</span>
<span class="nc" id="L3159">                        continueAfterPreliminaryCheck = true;</span>
<span class="nc" id="L3160">                      }</span>
                    }
<span class="pc bpc" id="L3162" title="1 of 2 branches missed.">                    if (continueAfterPreliminaryCheck) {</span>
                      // compute numbers;
<span class="fc" id="L3164">                      TermvectorNumberBasic numberBasic = computeTermvectorNumberBasic(</span>
                          docSet, termDocId, termsEnum, r, lrc, postingsEnum);
                      // register
<span class="fc bfc" id="L3167" title="All 2 branches covered.">                      if (numberBasic.docNumber &gt; 0) {</span>
<span class="fc" id="L3168">                        termCounter++;</span>
<span class="fc" id="L3169">                        registerStatus = registerValue(term, termVector,</span>
<span class="fc" id="L3170">                            numberBasic, termNumberMaximum, segmentNumber,</span>
                            false, mutableKey);
<span class="pc bpc" id="L3172" title="1 of 2 branches missed.">                        if (registerStatus != null) {</span>
<span class="nc" id="L3173">                          computeFullList.put(BytesRef.deepCopyOf(term),</span>
                              registerStatus);
                        }
                      }
                    }
                    // stop after termCounterMaximum
<span class="fc" id="L3179">                    if (termVector.subComponentFunction.sortType</span>
<span class="pc bpc" id="L3180" title="1 of 2 branches missed.">                        .equals(CodecUtil.SORT_TERM)</span>
                        &amp;&amp; termVector.subComponentFunction.sortDirection
<span class="nc bnc" id="L3182" title="All 4 branches missed.">                            .equals(CodecUtil.SORT_ASC)</span>
                        &amp;&amp; termCounter &gt;= termNumberMaximum) {
<span class="nc" id="L3184">                      break;</span>
                    }
                  }
                }
              }
              // rerun for full
<span class="pc bpc" id="L3190" title="1 of 2 branches missed.">              if (computeFullList.size() &gt; 0) {</span>
<span class="nc" id="L3191">                termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="nc bnc" id="L3192" title="All 2 branches missed.">                while ((term = termsEnum.next()) != null) {</span>
<span class="nc bnc" id="L3193" title="All 2 branches missed.">                  if (validateTermWithStartValue(term, termVector)) {</span>
<span class="nc" id="L3194">                    termDocId = -1;</span>
<span class="nc" id="L3195">                    mutableKey[0] = null;</span>
                    // only if (probably) needed
<span class="nc bnc" id="L3197" title="All 2 branches missed.">                    if (computeFullList.containsKey(term)) {</span>
<span class="nc" id="L3198">                      registerStatus = computeFullList.get(term);</span>
<span class="nc" id="L3199">                      if (termVector.subComponentFunction.sortType</span>
<span class="nc bnc" id="L3200" title="All 8 branches missed.">                          .equals(CodecUtil.SORT_TERM)</span>
                          || termVector.list != null
                          || termVector.boundaryRegistration
                          || registerStatus.force
                          || termVector.subComponentFunction.dataCollector
<span class="nc bnc" id="L3205" title="All 2 branches missed.">                              .validateSegmentBoundary(</span>
<span class="nc" id="L3206">                                  registerStatus.sortValue)) {</span>
<span class="nc" id="L3207">                        TermvectorNumberFull numberFull = computeTermvectorNumberFull(</span>
                            docSet, termDocId, termsEnum, r, lrc, postingsEnum,
                            positionsData);
<span class="nc bnc" id="L3210" title="All 2 branches missed.">                        if (numberFull.docNumber &gt; 0) {</span>
<span class="nc" id="L3211">                          termCounter++;</span>
<span class="nc" id="L3212">                          registerValue(term, termVector, numberFull,</span>
<span class="nc" id="L3213">                              termNumberMaximum, segmentNumber, mutableKey);</span>
                        }
<span class="nc" id="L3215">                      }</span>
                    }
                  }
                }
<span class="nc" id="L3219">                computeFullList.clear();</span>
              }
<span class="fc" id="L3221">            } else {</span>
<span class="nc" id="L3222">              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="L3228">            termVector.subComponentFunction.dataCollector</span>
<span class="fc" id="L3229">                .closeSegmentKeyValueRegistration();</span>
<span class="pc bpc" id="L3230" title="1 of 2 branches missed.">            if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3231" title="1 of 2 branches missed.">              for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3232">                function.dataCollector.closeSegmentKeyValueRegistration();</span>
<span class="nc" id="L3233">              }</span>
            }
          }
<span class="fc" id="L3236">          termVector.subComponentFunction.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L3237" title="1 of 2 branches missed.">          if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3238" title="1 of 2 branches missed.">            for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3239">              function.dataCollector.closeNewList();</span>
<span class="nc" id="L3240">            }</span>
          }
        }
<span class="fc" id="L3243">      }</span>
    }
<span class="fc" id="L3245">  }</span>

  /**
   * Creates the termvector second round.
   *
   * @param termVectorList
   *          the term vector list
   * @param positionsData
   *          the positions data
   * @param docSet
   *          the doc set
   * @param field
   *          the field
   * @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,
      HashMap&lt;Integer, Integer&gt; positionsData, List&lt;Integer&gt; docSet,
      String field, Terms t, LeafReader r, LeafReaderContext lrc)
      throws IOException {
<span class="pc bpc" id="L3272" title="1 of 2 branches missed.">    if (t != null) {</span>
      BytesRef term;
      TermsEnum termsEnum;
<span class="fc" id="L3275">      PostingsEnum postingsEnum = null;</span>
<span class="fc" id="L3276">      String segmentName = &quot;segment&quot; + lrc.ord;</span>
<span class="fc" id="L3277">      int segmentNumber = lrc.parent.leaves().size();</span>
<span class="fc" id="L3278">      String[] mutableKey = new String[1];</span>
<span class="fc bfc" id="L3279" title="All 2 branches covered.">      for (ComponentTermVector termVector : termVectorList) {</span>
<span class="pc bpc" id="L3280" title="1 of 4 branches missed.">        if (!termVector.full &amp;&amp; termVector.list == null) {</span>
<span class="pc bpc" id="L3281" title="1 of 2 branches missed.">          if (termVector.subComponentFunction.dataCollector.segmentRecomputeKeyList != null</span>
              &amp;&amp; termVector.subComponentFunction.dataCollector.segmentRecomputeKeyList
<span class="pc bpc" id="L3283" title="1 of 2 branches missed.">                  .containsKey(segmentName)) {</span>
<span class="fc" id="L3284">            HashSet&lt;String&gt; recomputeKeyList = termVector.subComponentFunction.dataCollector.segmentRecomputeKeyList</span>
<span class="fc" id="L3285">                .get(segmentName);</span>
<span class="pc bpc" id="L3286" title="1 of 2 branches missed.">            if (recomputeKeyList.size() &gt; 0) {</span>
<span class="fc" id="L3287">              HashMap&lt;String, Automaton&gt; automatonMap = MtasToken</span>
<span class="fc" id="L3288">                  .createAutomatonMap(termVector.prefix,</span>
<span class="fc" id="L3289">                      new ArrayList&lt;String&gt;(recomputeKeyList), true);</span>
<span class="fc" id="L3290">              List&lt;CompiledAutomaton&gt; listCompiledAutomata = MtasToken</span>
<span class="fc" id="L3291">                  .createAutomata(termVector.prefix, termVector.regexp,</span>
                      automatonMap);
<span class="fc bfc" id="L3293" title="All 2 branches covered.">              for (CompiledAutomaton compiledAutomaton : listCompiledAutomata) {</span>
<span class="fc" id="L3294">                termsEnum = t.intersect(compiledAutomaton, null);</span>
<span class="fc" id="L3295">                termVector.subComponentFunction.dataCollector.initNewList(</span>
                    termVector.subComponentFunction.dataCollector.segmentKeys
<span class="fc" id="L3297">                        .size(),</span>
                    segmentName, segmentNumber, termVector.boundary);
<span class="fc" id="L3299">                RegisterStatus registerStatus = null;</span>
<span class="pc bpc" id="L3300" title="1 of 2 branches missed.">                if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3301" title="1 of 2 branches missed.">                  for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3302">                    function.dataCollector.initNewList((int) t.size(),</span>
                        segmentName, segmentNumber, null);
<span class="nc" id="L3304">                  }</span>
                }
<span class="pc bpc" id="L3306" title="1 of 2 branches missed.">                if (docSet.size() &gt; 0) {</span>
                  int termDocId;
<span class="fc bfc" id="L3308" title="All 2 branches covered.">                  while ((term = termsEnum.next()) != null) {</span>
<span class="pc bpc" id="L3309" title="1 of 2 branches missed.">                    if (validateTermWithStartValue(term, termVector)) {</span>
<span class="fc" id="L3310">                      termDocId = -1;</span>
<span class="fc" id="L3311">                      mutableKey[0] = null;</span>
                      // compute numbers;
<span class="fc" id="L3313">                      TermvectorNumberBasic numberBasic = computeTermvectorNumberBasic(</span>
                          docSet, termDocId, termsEnum, r, lrc, postingsEnum);
<span class="fc bfc" id="L3315" title="All 2 branches covered.">                      if (numberBasic.docNumber &gt; 0) {</span>
<span class="fc" id="L3316">                        registerStatus = registerValue(term, termVector,</span>
<span class="fc" id="L3317">                            numberBasic, 0, segmentNumber, true, mutableKey);</span>
<span class="pc bpc" id="L3318" title="1 of 2 branches missed.">                        if (registerStatus != null) {</span>
<span class="nc" id="L3319">                          TermvectorNumberFull numberFull = computeTermvectorNumberFull(</span>
                              docSet, termDocId, termsEnum, r, lrc,
                              postingsEnum, positionsData);
<span class="nc bnc" id="L3322" title="All 2 branches missed.">                          if (numberFull.docNumber &gt; 0) {</span>
<span class="nc" id="L3323">                            registerValue(term, termVector, numberFull, 0,</span>
<span class="nc" id="L3324">                                segmentNumber, mutableKey);</span>
                          }
                        }
                      }
<span class="fc" id="L3328">                    }</span>
                  }
                }
<span class="fc" id="L3331">                termVector.subComponentFunction.dataCollector.closeNewList();</span>
<span class="pc bpc" id="L3332" title="1 of 2 branches missed.">                if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3333" title="1 of 2 branches missed.">                  for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L3334">                    function.dataCollector.closeNewList();</span>
<span class="nc" id="L3335">                  }</span>
                }
<span class="fc" id="L3337">              }</span>
            }
          }
        }
<span class="fc" id="L3341">      }</span>
    }
<span class="fc" id="L3343">  }</span>

  private static boolean validateTermWithStartValue(BytesRef term,
      ComponentTermVector termVector) {
<span class="pc bpc" id="L3347" title="1 of 2 branches missed.">    if (termVector.startValue == null) {</span>
<span class="fc" id="L3348">      return true;</span>
<span class="nc" id="L3349">    } else if (termVector.subComponentFunction.sortType</span>
<span class="nc bnc" id="L3350" title="All 2 branches missed.">        .equals(CodecUtil.SORT_TERM)) {</span>
<span class="nc bnc" id="L3351" title="All 2 branches missed.">      if (term.length &gt; termVector.startValue.length) {</span>
<span class="nc" id="L3352">        byte[] zeroBytes = (new BytesRef(&quot;\u0000&quot;)).bytes;</span>
<span class="nc" id="L3353">        int n = (int) (Math</span>
<span class="nc" id="L3354">            .ceil(((double) (term.length - termVector.startValue.length))</span>
                / zeroBytes.length));
<span class="nc" id="L3356">        byte[] newBytes = new byte[termVector.startValue.length</span>
            + n * zeroBytes.length];
<span class="nc" id="L3358">        System.arraycopy(termVector.startValue.bytes, 0, newBytes, 0,</span>
            termVector.startValue.length);
<span class="nc bnc" id="L3360" title="All 2 branches missed.">        for (int i = 0; i &lt; n; i++) {</span>
<span class="nc" id="L3361">          System.arraycopy(zeroBytes, 0, newBytes,</span>
              termVector.startValue.length + i * zeroBytes.length,
              zeroBytes.length);
        }
<span class="nc" id="L3365">        termVector.startValue = new BytesRef(newBytes);</span>
      }
<span class="nc bnc" id="L3367" title="All 2 branches missed.">      if (termVector.subComponentFunction.sortDirection.equals(</span>
<span class="nc bnc" id="L3368" title="All 2 branches missed.">          CodecUtil.SORT_ASC) &amp;&amp; (termVector.startValue.compareTo(term) &lt; 0)) {</span>
<span class="nc" id="L3369">        return true;</span>
<span class="nc bnc" id="L3370" title="All 2 branches missed.">      } else if (termVector.subComponentFunction.sortDirection.equals(</span>
<span class="nc bnc" id="L3371" title="All 2 branches missed.">          CodecUtil.SORT_DESC) &amp;&amp; (termVector.startValue.compareTo(term) &gt; 0)) {</span>
<span class="nc" id="L3372">        return true;</span>
      }
    }
<span class="nc" id="L3375">    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="L3389">    boolean needSecondRound = false;</span>
<span class="fc bfc" id="L3390" title="All 2 branches covered.">    for (ComponentTermVector termVector : termVectorList) {</span>
<span class="pc bpc" id="L3391" title="1 of 4 branches missed.">      if (!termVector.full &amp;&amp; termVector.list == null) {</span>
<span class="pc bpc" id="L3392" title="1 of 2 branches missed.">        if (termVector.subComponentFunction.dataCollector.segmentRegistration != null</span>
            &amp;&amp; (termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="pc bpc" id="L3394" title="1 of 2 branches missed.">                .equals(MtasDataCollector.SEGMENT_SORT_ASC)</span>
                || termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="pc bpc" id="L3396" title="2 of 4 branches missed.">                    .equals(MtasDataCollector.SEGMENT_SORT_DESC))</span>
            &amp;&amp; termVector.number &gt; 0) {
<span class="fc" id="L3398">          termVector.subComponentFunction.dataCollector.recomputeSegmentKeys();</span>
<span class="fc" id="L3399">          if (!termVector.subComponentFunction.dataCollector</span>
<span class="pc bpc" id="L3400" title="1 of 2 branches missed.">              .checkExistenceNecessaryKeys()) {</span>
<span class="fc" id="L3401">            needSecondRound = true;</span>
          }
<span class="fc" id="L3403">          termVector.subComponentFunction.dataCollector.reduceToSegmentKeys();</span>
<span class="nc bnc" id="L3404" title="All 2 branches missed.">        } else if (termVector.subComponentFunction.dataCollector.segmentRegistration != null</span>
            &amp;&amp; (termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="nc bnc" id="L3406" title="All 2 branches missed.">                .equals(MtasDataCollector.SEGMENT_BOUNDARY_ASC)</span>
                || termVector.subComponentFunction.dataCollector.segmentRegistration
<span class="nc bnc" id="L3408" title="All 4 branches missed.">                    .equals(MtasDataCollector.SEGMENT_BOUNDARY_DESC))</span>
            &amp;&amp; termVector.number &gt; 0) {
<span class="nc" id="L3410">          termVector.subComponentFunction.dataCollector.recomputeSegmentKeys();</span>
<span class="nc" id="L3411">          if (!termVector.subComponentFunction.dataCollector</span>
<span class="nc bnc" id="L3412" title="All 2 branches missed.">              .checkExistenceNecessaryKeys()) {</span>
<span class="nc" id="L3413">            needSecondRound = true;</span>
          }
<span class="nc" id="L3415">          termVector.subComponentFunction.dataCollector.reduceToSegmentKeys();</span>
        }
      }
<span class="fc" id="L3418">    }</span>
<span class="fc" id="L3419">    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="L3436">    TermvectorNumberBasic() {</span>
<span class="fc" id="L3437">      valueSum = new long[] { 0 };</span>
<span class="fc" id="L3438">      docNumber = 0;</span>
<span class="fc" id="L3439">    }</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="nc" id="L3462">    TermvectorNumberFull(int maxSize) {</span>
<span class="nc" id="L3463">      args = new long[maxSize];</span>
<span class="nc" id="L3464">      positions = new int[maxSize];</span>
<span class="nc" id="L3465">      docNumber = 0;</span>
<span class="nc" id="L3466">    }</span>
  }

  /**
   * The Class RegisterStatus.
   */
<span class="nc" id="L3472">  private static class RegisterStatus {</span>

    /** 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="nc" id="L3488">    RegisterStatus(long sortValue, boolean force) {</span>
<span class="nc" id="L3489">      this.sortValue = sortValue;</span>
<span class="nc" id="L3490">      this.force = force;</span>
<span class="nc" id="L3491">    }</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="L3520">    long value = termVector.subComponentFunction.parserFunction</span>
<span class="fc" id="L3521">        .getValueLong(number.valueSum, 0);</span>
<span class="fc" id="L3522">    long sortValue = 0;</span>
<span class="fc" id="L3523">    if (termVector.subComponentFunction.sortType</span>
<span class="pc bpc" id="L3524" title="1 of 2 branches missed.">        .equals(CodecUtil.STATS_TYPE_SUM)) {</span>
<span class="fc" id="L3525">      sortValue = value;</span>
<span class="nc" id="L3526">    } else if (termVector.subComponentFunction.sortType</span>
<span class="nc bnc" id="L3527" title="All 2 branches missed.">        .equals(CodecUtil.STATS_TYPE_N)) {</span>
<span class="nc" id="L3528">      sortValue = Long.valueOf(number.docNumber);</span>
    }
<span class="fc" id="L3530">    boolean addItem = false, addItemForced = false;</span>
<span class="fc" id="L3531">    MtasDataCollector&lt;Long, ?&gt; dataCollector = (MtasDataCollector&lt;Long, ?&gt;) termVector.subComponentFunction.dataCollector;</span>
<span class="pc bpc" id="L3532" title="1 of 2 branches missed.">    if (termVector.subComponentFunction.sortType.equals(CodecUtil.SORT_TERM)) {</span>
<span class="nc" id="L3533">      addItem = true;</span>
<span class="nc" id="L3534">      addItemForced = true;</span>
<span class="fc" id="L3535">    } else if (termVector.subComponentFunction.sortType</span>
<span class="pc bpc" id="L3536" title="1 of 2 branches missed.">        .equals(CodecUtil.STATS_TYPE_SUM)</span>
        || termVector.subComponentFunction.sortType
<span class="nc bnc" id="L3538" title="All 2 branches missed.">            .equals(CodecUtil.STATS_TYPE_N)) {</span>
<span class="fc bfc" id="L3539" title="All 2 branches covered.">      if (forceAccept) {</span>
<span class="fc" id="L3540">        addItem = true;</span>
<span class="fc" id="L3541">        addItemForced = addItem;</span>
<span class="pc bpc" id="L3542" title="1 of 2 branches missed.">      } else if (termVector.boundaryRegistration) {</span>
<span class="nc" id="L3543">        addItem = dataCollector.validateSegmentBoundary(sortValue);</span>
<span class="nc bnc" id="L3544" title="All 2 branches missed.">        if (addItem) {</span>
<span class="nc bnc" id="L3545" title="All 2 branches missed.">          if (mutableKey[0] == null) {</span>
<span class="nc" id="L3546">            mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
          }
<span class="nc" id="L3548">          String segmentStatus = dataCollector.validateSegmentValue(</span>
<span class="nc" id="L3549">              mutableKey[0], sortValue, termNumberMaximum, segmentNumber,</span>
              false);
<span class="nc bnc" id="L3551" title="All 2 branches missed.">          if (segmentStatus != null) {</span>
<span class="nc bnc" id="L3552" title="All 2 branches missed.">            if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY)) {</span>
<span class="nc" id="L3553">              addItemForced = true;</span>
            }
          } else {
            // shouldn't happen
          }
<span class="nc" id="L3558">        }</span>
      } else {
<span class="fc" id="L3560">        String segmentStatus = dataCollector.validateSegmentValue(sortValue,</span>
<span class="fc" id="L3561">            termNumberMaximum, segmentNumber);</span>
<span class="fc bfc" id="L3562" title="All 2 branches covered.">        if (segmentStatus != null) {</span>
          boolean possibleAddItem;
<span class="fc bfc" id="L3564" title="All 2 branches covered.">          if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY_OR_NEW)) {</span>
<span class="fc" id="L3565">            possibleAddItem = true;</span>
<span class="fc" id="L3566">          } else if (segmentStatus</span>
<span class="pc bpc" id="L3567" title="1 of 2 branches missed.">              .equals(MtasDataCollector.SEGMENT_POSSIBLE_KEY)) {</span>
<span class="fc" id="L3568">            mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
<span class="fc" id="L3569">            segmentStatus = dataCollector.validateSegmentValue(mutableKey[0],</span>
<span class="fc" id="L3570">                sortValue, termNumberMaximum, segmentNumber, true);</span>
<span class="fc bfc" id="L3571" title="All 2 branches covered.">            if (segmentStatus != null) {</span>
<span class="fc" id="L3572">              possibleAddItem = true;</span>
            } else {
<span class="fc" id="L3574">              possibleAddItem = false;</span>
            }
          } else {
            // should never happen?
<span class="nc" id="L3578">            possibleAddItem = false;</span>
          }
<span class="fc bfc" id="L3580" title="All 2 branches covered.">          if (possibleAddItem) {</span>
<span class="fc bfc" id="L3581" title="All 2 branches covered.">            if (mutableKey[0] == null) {</span>
<span class="fc" id="L3582">              mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
            }
<span class="fc" id="L3584">            segmentStatus = dataCollector.validateSegmentValue(mutableKey[0],</span>
<span class="fc" id="L3585">                sortValue, termNumberMaximum, segmentNumber, false);</span>
<span class="pc bpc" id="L3586" title="1 of 2 branches missed.">            if (segmentStatus != null) {</span>
<span class="fc" id="L3587">              addItem = true;</span>
<span class="fc bfc" id="L3588" title="All 2 branches covered.">              if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY)) {</span>
<span class="fc" id="L3589">                addItemForced = true;</span>
              }
            }
          }
<span class="fc" id="L3593">        } else {</span>
<span class="fc" id="L3594">          addItem = false;</span>
        }
<span class="fc" id="L3596">      }</span>
    } else {
<span class="nc" id="L3598">      addItem = false;</span>
    }
<span class="fc bfc" id="L3600" title="All 2 branches covered.">    if (addItem) {</span>
<span class="fc" id="L3601">      boolean computeFull = false;</span>
<span class="fc bfc" id="L3602" title="All 2 branches covered.">      if (mutableKey[0] == null) {</span>
<span class="fc" id="L3603">        mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
      }
<span class="fc" id="L3605">      if (termVector.subComponentFunction.statsType</span>
<span class="pc bpc" id="L3606" title="1 of 2 branches missed.">          .equals(CodecUtil.STATS_BASIC)) {</span>
<span class="fc" id="L3607">        dataCollector.add(mutableKey[0], value, number.docNumber);</span>
      } else {
<span class="nc" id="L3609">        computeFull = true;</span>
      }
<span class="pc bpc" id="L3611" title="1 of 2 branches missed.">      if (termVector.functions != null) {</span>
<span class="pc bpc" id="L3612" title="1 of 2 branches missed.">        for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc bnc" id="L3613" title="All 2 branches missed.">          if (function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L3614" title="All 2 branches missed.">              &amp;&amp; !function.parserFunction.needPositions()</span>
<span class="nc bnc" id="L3615" title="All 2 branches missed.">              &amp;&amp; function.statsType.equals(CodecUtil.STATS_BASIC)) {</span>
<span class="nc bnc" id="L3616" title="All 2 branches missed.">            if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L3617">              long valueFunction = function.parserFunction</span>
<span class="nc" id="L3618">                  .getValueLong(number.valueSum, 0);</span>
<span class="nc" id="L3619">              function.dataCollector.add(mutableKey[0], valueFunction,</span>
                  number.docNumber);
<span class="nc bnc" id="L3621" title="All 2 branches missed.">            } else if (function.dataType.equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L3622">              double valueFunction = function.parserFunction</span>
<span class="nc" id="L3623">                  .getValueDouble(number.valueSum, 0);</span>
<span class="nc" id="L3624">              function.dataCollector.add(mutableKey[0], valueFunction,</span>
                  number.docNumber);
<span class="nc" id="L3626">            }</span>
          } else {
<span class="nc" id="L3628">            computeFull = true;</span>
          }
<span class="nc" id="L3630">        }</span>
      }
<span class="pc bpc" id="L3632" title="1 of 2 branches missed.">      return computeFull ? new RegisterStatus(sortValue, addItemForced) : null;</span>
    } else {
<span class="fc" id="L3634">      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="L3661">    long sortValue = 0;</span>
<span class="nc" id="L3662">    if (!termVector.subComponentFunction.sortDirection</span>
<span class="nc bnc" id="L3663" title="All 2 branches missed.">        .equals(CodecUtil.SORT_DESC)) {</span>
<span class="nc" id="L3664">      return true;</span>
<span class="nc" id="L3665">    } else if (termVector.subComponentFunction.sortType</span>
<span class="nc bnc" id="L3666" title="All 2 branches missed.">        .equals(CodecUtil.STATS_TYPE_SUM)) {</span>
<span class="nc" id="L3667">      sortValue = termVector.subComponentFunction.parserFunction</span>
<span class="nc" id="L3668">          .getValueLong(number.valueSum, 0);</span>
<span class="nc" id="L3669">    } else if (termVector.subComponentFunction.sortType</span>
<span class="nc bnc" id="L3670" title="All 2 branches missed.">        .equals(CodecUtil.STATS_TYPE_N)) {</span>
<span class="nc" id="L3671">      sortValue = Long.valueOf(number.docNumber);</span>
    } else {
<span class="nc" id="L3673">      return true;</span>
    }
<span class="nc" id="L3675">    MtasDataCollector&lt;Long, ?&gt; dataCollector = (MtasDataCollector&lt;Long, ?&gt;) termVector.subComponentFunction.dataCollector;</span>
<span class="nc bnc" id="L3676" title="All 2 branches missed.">    if (termVector.boundaryRegistration) {</span>
<span class="nc" id="L3677">      return dataCollector.validateSegmentBoundary(sortValue);</span>
    } else {
<span class="nc" id="L3679">      String segmentStatus = dataCollector.validateSegmentValue(sortValue,</span>
<span class="nc" id="L3680">          termNumberMaximum, segmentNumber);</span>
<span class="nc bnc" id="L3681" title="All 2 branches missed.">      if (segmentStatus != null) {</span>
<span class="nc bnc" id="L3682" title="All 2 branches missed.">        if (segmentStatus.equals(MtasDataCollector.SEGMENT_KEY_OR_NEW)) {</span>
<span class="nc" id="L3683">          return true;</span>
<span class="nc" id="L3684">        } else if (segmentStatus</span>
<span class="nc bnc" id="L3685" title="All 2 branches missed.">            .equals(MtasDataCollector.SEGMENT_POSSIBLE_KEY)) {</span>
<span class="nc" id="L3686">          mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
<span class="nc" id="L3687">          segmentStatus = dataCollector.validateSegmentValue(mutableKey[0],</span>
<span class="nc" id="L3688">              sortValue, termNumberMaximum, segmentNumber, true);</span>
<span class="nc bnc" id="L3689" title="All 2 branches missed.">          if (segmentStatus != null) {</span>
<span class="nc" id="L3690">            return true;</span>
          } else {
<span class="nc" id="L3692">            return false;</span>
          }
        } else {
          // should never happen?
<span class="nc" id="L3696">          return false;</span>
        }
      } else {
<span class="nc" id="L3699">        return false;</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 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,
      Integer termNumberMaximum, Integer segmentNumber, String[] mutableKey)
      throws IOException {
<span class="nc bnc" id="L3727" title="All 2 branches missed.">    if (number.docNumber &gt; 0) {</span>
<span class="nc bnc" id="L3728" title="All 2 branches missed.">      if (mutableKey[0] == null) {</span>
<span class="nc" id="L3729">        mutableKey[0] = MtasToken.getPostfixFromValue(term);</span>
      }
<span class="nc" id="L3731">      MtasDataCollector&lt;Long, ?&gt; dataCollector = (MtasDataCollector&lt;Long, ?&gt;) termVector.subComponentFunction.dataCollector;</span>
<span class="nc" id="L3732">      long[] valuesLong = new long[number.docNumber];</span>
<span class="nc bnc" id="L3733" title="All 2 branches missed.">      for (int i = 0; i &lt; number.docNumber; i++) {</span>
        try {
<span class="nc" id="L3735">          valuesLong[i] = termVector.subComponentFunction.parserFunction</span>
<span class="nc" id="L3736">              .getValueLong(new long[] { number.args[i] }, number.positions[i]);</span>
<span class="nc" id="L3737">        } catch (IOException e) {</span>
<span class="nc" id="L3738">          dataCollector.error(mutableKey[0], e.getMessage());</span>
<span class="nc" id="L3739">        }</span>
      }
<span class="nc" id="L3741">      if (!termVector.subComponentFunction.statsType</span>
<span class="nc bnc" id="L3742" title="All 2 branches missed.">          .equals(CodecUtil.STATS_BASIC)) {</span>
<span class="nc" id="L3743">        dataCollector.add(mutableKey[0], valuesLong, valuesLong.length);</span>
      }
<span class="nc bnc" id="L3745" title="All 2 branches missed.">      for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc bnc" id="L3746" title="All 2 branches missed.">        if (!function.parserFunction.sumRule()</span>
<span class="nc bnc" id="L3747" title="All 2 branches missed.">            || function.parserFunction.needPositions()</span>
<span class="nc bnc" id="L3748" title="All 2 branches missed.">            || !function.statsType.equals(CodecUtil.STATS_BASIC)) {</span>
<span class="nc bnc" id="L3749" title="All 2 branches missed.">          if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {</span>
<span class="nc" id="L3750">            valuesLong = new long[number.docNumber];</span>
<span class="nc bnc" id="L3751" title="All 2 branches missed.">            for (int i = 0; i &lt; number.docNumber; i++) {</span>
              try {
<span class="nc" id="L3753">                valuesLong[i] = function.parserFunction.getValueLong(</span>
                    new long[] { number.args[i] }, number.positions[i]);
<span class="nc" id="L3755">              } catch (IOException e) {</span>
<span class="nc" id="L3756">                function.dataCollector.error(mutableKey[0], e.getMessage());</span>
<span class="nc" id="L3757">              }</span>
            }
<span class="nc" id="L3759">            function.dataCollector.add(mutableKey[0], valuesLong,</span>
                valuesLong.length);
<span class="nc bnc" id="L3761" title="All 2 branches missed.">          } else if (function.dataType.equals(CodecUtil.DATA_TYPE_DOUBLE)) {</span>
<span class="nc" id="L3762">            double[] valuesDouble = new double[number.docNumber];</span>
<span class="nc bnc" id="L3763" title="All 2 branches missed.">            for (int i = 0; i &lt; number.docNumber; i++) {</span>
              try {
<span class="nc" id="L3765">                valuesDouble[i] = function.parserFunction.getValueDouble(</span>
                    new long[] { number.args[i] }, number.positions[i]);
<span class="nc" id="L3767">              } catch (IOException e) {</span>
<span class="nc" id="L3768">                function.dataCollector.error(mutableKey[0], e.getMessage());</span>
<span class="nc" id="L3769">              }</span>
            }
<span class="nc" id="L3771">            function.dataCollector.add(mutableKey[0], valuesDouble,</span>
                valuesDouble.length);
          }
        }
<span class="nc" id="L3775">      }</span>
    }
<span class="nc" id="L3777">  }</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="L3792">    TermvectorNumberBasic result = new TermvectorNumberBasic();</span>
<span class="pc bpc" id="L3793" title="1 of 2 branches missed.">    boolean hasDeletedDocuments = (r.getLiveDocs() != null);</span>
<span class="pc bpc" id="L3794" title="1 of 2 branches missed.">    if (!hasDeletedDocuments) {</span>
<span class="fc" id="L3795">      result.valueSum[0] = termsEnum.totalTermFreq();</span>
<span class="fc" id="L3796">      result.docNumber = termsEnum.docFreq();</span>
<span class="pc bpc" id="L3797" title="1 of 2 branches missed.">      if (result.valueSum[0] &gt; -1) {</span>
<span class="fc" id="L3798">        return result;</span>
      }
    }
<span class="nc" id="L3801">    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="L3826">    TermvectorNumberBasic result = new TermvectorNumberBasic();</span>
<span class="fc bfc" id="L3827" title="All 2 branches covered.">    boolean hasDeletedDocuments = (r.getLiveDocs() != null);</span>
<span class="pc bpc" id="L3828" title="1 of 4 branches missed.">    if ((docSet.size() == r.numDocs()) &amp;&amp; !hasDeletedDocuments) {</span>
      try {
<span class="fc" id="L3830">        return computeTermvectorNumberBasic(termsEnum, r);</span>
<span class="nc" id="L3831">      } catch (IOException e) {</span>
        // problem
      }
    }
<span class="fc" id="L3835">    result.docNumber = 0;</span>
<span class="fc" id="L3836">    result.valueSum[0] = 0;</span>
<span class="fc" id="L3837">    Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="fc" id="L3838">    postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.FREQS);</span>
    int docId;
<span class="fc bfc" id="L3840" title="All 2 branches covered.">    while (docIterator.hasNext()) {</span>
<span class="fc" id="L3841">      docId = docIterator.next() - lrc.docBase;</span>
<span class="pc bpc" id="L3842" title="1 of 2 branches missed.">      if (docId &gt;= termDocId) {</span>
<span class="pc bpc" id="L3843" title="1 of 2 branches missed.">        if ((docId == termDocId)</span>
<span class="fc bfc" id="L3844" title="All 2 branches covered.">            || ((termDocId = postingsEnum.advance(docId)) == docId)) {</span>
<span class="fc" id="L3845">          result.docNumber++;</span>
<span class="fc" id="L3846">          result.valueSum[0] += postingsEnum.freq();</span>
        }
      }
<span class="pc bpc" id="L3849" title="1 of 2 branches missed.">      if (termDocId == DocIdSetIterator.NO_MORE_DOCS) {</span>
<span class="nc" id="L3850">        break;</span>
      }
    }
<span class="fc" id="L3853">    return result;</span>
  }

  /**
   * Compute termvector number full.
   *
   * @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
   * @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, LeafReader r,
      LeafReaderContext lrc, PostingsEnum postingsEnum,
      HashMap&lt;Integer, Integer&gt; positionsData) throws IOException {
<span class="nc" id="L3881">    TermvectorNumberFull result = new TermvectorNumberFull(docSet.size());</span>
<span class="nc" id="L3882">    Iterator&lt;Integer&gt; docIterator = docSet.iterator();</span>
<span class="nc" id="L3883">    postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.FREQS);</span>
<span class="nc bnc" id="L3884" title="All 2 branches missed.">    while (docIterator.hasNext()) {</span>
<span class="nc" id="L3885">      int docId = docIterator.next() - lrc.docBase;</span>
<span class="nc bnc" id="L3886" title="All 2 branches missed.">      if (docId &gt;= termDocId) {</span>
<span class="nc bnc" id="L3887" title="All 2 branches missed.">        if ((docId == termDocId)</span>
<span class="nc bnc" id="L3888" title="All 2 branches missed.">            || ((termDocId = postingsEnum.advance(docId)) == docId)) {</span>
<span class="nc" id="L3889">          result.args[result.docNumber] = postingsEnum.freq();</span>
<span class="nc bnc" id="L3890" title="All 2 branches missed.">          result.positions[result.docNumber] = (positionsData == null) ? 0</span>
<span class="nc" id="L3891">              : positionsData.get(docId + lrc.docBase);</span>
<span class="nc" id="L3892">          result.docNumber++;</span>
        }
      }
<span class="nc" id="L3895">    }</span>

<span class="nc" id="L3897">    return result;</span>
  }

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