docs: @Override
    protected HashMap<String, Object> getDistribution(String argument) {
      HashMap<String, Object> result = new LinkedHashMap<>();
      Long start = null;
      Long end = null;
      Long step = null;
      Integer number = null;
      if (argument != null) {
        Matcher m = fpArgument.matcher(argument);
        // get settings
        while (m.find()) {
          if (m.group(1).trim().equals("start")) {
            start = Long.parseLong(m.group(2));
          } else if (m.group(1).trim().equals("end")) {
            end = Long.parseLong(m.group(2));
          } else if (m.group(1).trim().equals("step")) {
            step = Long.parseLong(m.group(2));
          } else if (m.group(1).trim().equals("number")) {
            number = Integer.parseInt(m.group(2));
          }
        }
      }
      // always exactly one of (positive) number and (positive) step, other null
      if ((number == null || number < 1) && (step == null || step < 1)) {
        number = 10;
        step = null;
      } else if (step != null && step < 1) {
        step = null;
      } else if (number != null && number < 1) {
        number = null;
      } else if (step != null) {
        number = null;
      }
      // sanity checks start/end
      createStats();
      long tmpStart = Double.valueOf(Math.floor(stats.getMin())).longValue();
      long tmpEnd = Double.valueOf(Math.ceil(stats.getMax())).longValue();
      if (start != null && end != null && start > end) {
        return null;
      } else if (start != null && start > tmpEnd) {
        return null;
      } else if (end != null && end < tmpStart) {
        return null;
      }
      // check start and end
      if (start == null && end == null) {
        if (step == null) {
          step = -Math.floorDiv((tmpStart - tmpEnd - 1), number);
        }
        number = Long.valueOf(-Math.floorDiv((tmpStart - tmpEnd - 1), step))
            .intValue();
        start = tmpStart;
        end = start + (number * step);
      } else if (start == null) {
        if (step == null) {
          step = -Math.floorDiv((tmpStart - end - 1), number);
        }
        number = Long.valueOf(-Math.floorDiv((tmpStart - end - 1), step))
            .intValue();
        start = end - (number * step);
      } else if (end == null) {
        if (step == null) {
          step = -Math.floorDiv((start - tmpEnd - 1), number);
        }
        number = Long.valueOf(-Math.floorDiv((start - tmpEnd - 1), step))
            .intValue();
        end = start + (number * step);
      } else {
        if (step == null) {
          step = -Math.floorDiv((start - end - 1), number);
        }
        number = Long.valueOf(-Math.floorDiv((start - end - 1), step)).intValue();
      }
      long[] list = new long[number];
      for (Long v : fullValues) {
        if (v >= start && v <= end) {
          int i = Long.valueOf(Math.floorDiv((v - start), step)).intValue();
          list[i]++;
        }
      }
      for (int i = 0; i < number; i++) {
        Long l = start + i * step;
        Long r = Math.min(end, l + step - 1);
        String key;
        if (step > 1 && r > l) {
          key = "[" + l + "," + r + "]";
        } else {
          key = "[" + l + "]";
        }
        result.put(key, list[i]);
      }
      return result;
    }