docs: private static void createStats(List<ComponentSpan> statsSpanList,
        Map<Integer, Integer> positionsData,
        Map<MtasSpanQuery, Map<Integer, Integer>> spansNumberData,
        Integer[] docSet) throws IOException {
      if (statsSpanList != null) {
        for (ComponentSpan span : statsSpanList) {
          if (span.parser.needArgumentsNumber() > span.queries.length) {
            throw new IOException(
                "function " + span.parser + " expects (at least) "
                    + span.parser.needArgumentsNumber() + " queries");
          }
          // collect
          Map<Integer, long[]> args = computeArguments(spansNumberData,
              span.queries, docSet);
          if (span.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {
            // try to call functionParser as little as possible
            if (span.statsType.equals(CodecUtil.STATS_BASIC)
                && (span.minimumLong == null) && (span.maximumLong == null)
                && (span.functions == null
                    || (span.functionBasic() && span.functionSumRule()
                        && !span.functionNeedPositions()))) {
              // initialise
              int length = span.parser.needArgumentsNumber();
              long[] valueSum = new long[length];
              long valuePositions = 0;
              // collect
              if (docSet.length > 0) {
                long[] tmpArgs;
                for (int docId : docSet) {
                  tmpArgs = args.get(docId);
                  valuePositions += (positionsData == null) ? 0
                      : positionsData.get(docId);
                  if (tmpArgs != null) {
                    for (int i = 0; i < length; i++) {
                      valueSum[i] += tmpArgs[i];
                    }
                  }
                }
                long valueLong;
                span.dataCollector.initNewList(1);
                try {
                  valueLong = span.parser.getValueLong(valueSum, valuePositions);
                  span.dataCollector.add(valueLong, docSet.length);
                } catch (IOException e) {
                  log.debug(e);
                  span.dataCollector.error(e.getMessage());
                }
                if (span.functions != null) {
                  for (SubComponentFunction function : span.functions) {
                    function.dataCollector.initNewList(1);
                    if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {
                      try {
                        valueLong = function.parserFunction.getValueLong(valueSum,
                            valuePositions);
                        function.dataCollector.add(valueLong, docSet.length);
                      } catch (IOException e) {
                        log.debug(e);
                        function.dataCollector.error(e.getMessage());
                      }
                    } else if (function.dataType
                        .equals(CodecUtil.DATA_TYPE_DOUBLE)) {
                      try {
                        double valueDouble = function.parserFunction
                            .getValueDouble(valueSum, valuePositions);
                        function.dataCollector.add(valueDouble, docSet.length);
                      } catch (IOException e) {
                        log.debug(e);
                        function.dataCollector.error(e.getMessage());
                      }
                    } else {
                      throw new IOException(
                          "can't handle function dataType " + function.dataType);
                    }
                    function.dataCollector.closeNewList();
                  }
                }
                span.dataCollector.closeNewList();
              }
            } else {
              // collect
              if (docSet.length > 0) {
                int number = 0;
                int positions;
                long valueLong;
                double valueDouble;
                long[] values = new long[docSet.length];
                long[][] functionValuesLong = null;
                double[][] functionValuesDouble = null;
                span.dataCollector.initNewList(1);
                if (span.functions != null) {
                  functionValuesLong = new long[span.functions.size()][];
                  functionValuesDouble = new double[span.functions.size()][];
                  for (int i = 0; i < span.functions.size(); i++) {
                    SubComponentFunction function = span.functions.get(i);
                    if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {
                      functionValuesLong[i] = new long[docSet.length];
                      functionValuesDouble[i] = null;
                    } else if (function.dataType
                        .equals(CodecUtil.DATA_TYPE_DOUBLE)) {
                      functionValuesLong[i] = null;
                      functionValuesDouble[i] = new double[docSet.length];
                    }
                    function.dataCollector.initNewList(1);
                  }
                }
                for (int docId : docSet) {
                  if (positionsData == null) {
                    positions = 0;
                  } else {
                    positions = (positionsData.get(docId) == null ? 0
                        : positionsData.get(docId));
                  }
                  valueLong = span.parser.getValueLong(args.get(docId),
                      positions);
                  if (((span.minimumLong == null)
                      || (valueLong >= span.minimumLong))
                      && ((span.maximumLong == null)
                          || (valueLong <= span.maximumLong))) {
                    values[number] = valueLong;
                    if (span.functions != null) {
                      for (int i = 0; i < span.functions.size(); i++) {
                        SubComponentFunction function = span.functions.get(i);
                        try {
                          if (function.dataType
                              .equals(CodecUtil.DATA_TYPE_LONG)) {
                            valueLong = function.parserFunction
                                .getValueLong(args.get(docId), positions);
                            functionValuesLong[i][number] = valueLong;
                          } else if (function.dataType
                              .equals(CodecUtil.DATA_TYPE_DOUBLE)) {
                            valueDouble = function.parserFunction
                                .getValueDouble(args.get(docId), positions);
                            functionValuesDouble[i][number] = valueDouble;
                          }
                        } catch (IOException e) {
                          log.debug(e);
                          function.dataCollector.error(e.getMessage());
                        }
                      }
                    }
                    number++;
                  }
                }
                if (number > 0) {
                  span.dataCollector.add(values, number);
                  if (span.functions != null) {
                    for (int i = 0; i < span.functions.size(); i++) {
                      SubComponentFunction function = span.functions.get(i);
                      if (function.dataType.equals(CodecUtil.DATA_TYPE_LONG)) {
                        function.dataCollector.add(functionValuesLong[i], number);
                      } else if (function.dataType
                          .equals(CodecUtil.DATA_TYPE_DOUBLE)) {
                        function.dataCollector.add(functionValuesDouble[i],
                            number);
                      }
                    }
                  }
                }
                span.dataCollector.closeNewList();
                if (span.functions != null) {
                  for (SubComponentFunction function : span.functions) {
                    function.dataCollector.closeNewList();
                  }
                }
              }
            }
          } else {
            throw new IOException("unexpected dataType " + span.dataType);
          }
        }
      }
    }