private static @NotNull @Nls String formatDuration(long duration,
                                                     MeasureUnit durationTimeUnit, int maxFragments,
                                                     boolean narrow) {
    LongArrayList unitValues = new LongArrayList();
    IntList unitIndices = new IntArrayList();

    long count = duration;
    int i = 0;
    while (TIME_UNITS[i] != durationTimeUnit) {
      i++;
      if (i == TIME_UNITS.length) {
        // Will never be called in a practical case, since the converter produces only those time units that are already in the array
        // However, it can be called theoretically, since the converter can be changed
        throw new IllegalArgumentException("Duration time unit doesn't exists in all time units");
      }
    }
    int startPosition = i;
    i++;
    for (; i < TIME_UNITS.length && count > 0; i++) {
      long multiplier = TIME_MULTIPLIERS[i];
      if (count < multiplier) break;
      long remainder = count % multiplier;
      count /= multiplier;
      if (remainder != 0 || !unitValues.isEmpty()) {
        unitValues.add(0, remainder);
        unitIndices.add(0, i - 1);
      }
    }
    unitValues.add(0, count);
    unitIndices.add(0, i - 1);

    if (unitValues.size() > maxFragments) {
      int lastUnitIndex = unitIndices.getInt(maxFragments - 1);
      long lastMultiplier = TIME_MULTIPLIERS[lastUnitIndex];
      // Round up if needed
      if (unitValues.getLong(maxFragments) > lastMultiplier / 2) {
        long increment = lastMultiplier - unitValues.getLong(maxFragments);
        for (int unit = lastUnitIndex - 1; unit > startPosition; unit--) {
          increment *= TIME_MULTIPLIERS[unit];
        }
        return new NlsDurationFormatter()
          .setDurationMeasureTimeUnit(durationTimeUnit)
          .setNarrow(narrow)
          .setMaxFragments(maxFragments)
          .formatDuration(duration + increment);
      }
    }

    int finalCount = Math.min(unitValues.size(), maxFragments);
    CachedFormats formats = getFormats();
    if (narrow) {
      List<String> fragments = new ArrayList<>();
      for (i = 0; i < finalCount; i++) {
        fragments.add(formats.shortNumberUnitFormatters[unitIndices.getInt(i)]
                        .format(unitValues.getLong(i)).toString().replace(' ', '\u2009'));
      }
      return StringUtil.join(fragments, " ");
    }
    MeasureFormat format = formats.shortFormat;
    Measure[] measures = new Measure[finalCount];
    for (i = 0; i < finalCount; i++) {
      measures[i] = new Measure(unitValues.getLong(i), TIME_UNITS[unitIndices.getInt(i)]);
    }
    return format.formatMeasures(measures);
  }
private static @NotNull @Nls String formatDuration(long duration,
                                                     MeasureUnit durationTimeUnit, int maxFragments,
                                                     boolean narrow)