docs: public static IntGenerator parseIntRanges(String str) {
      ArrayList<IntGenerator> generators = new ArrayList<>();
      IntegerArray ints = new IntegerArray();
      int last = Integer.MAX_VALUE; // Last seen integer
      for(int pos = 0, next = -1; pos < str.length(); pos = next + 1) {
        // Find next comma:
        next = nextSep(str, pos);
        // Syntaxes involving ",," or ",..," or ",...," equivalently:
        if(next == pos || (str.charAt(pos) == '.' && //
            ((next - pos == 2 && str.charAt(pos + 1) == '.') //
                || (next - pos == 3 && str.charAt(pos + 1) == '.' && str.charAt(pos + 2) == '.')))) {
          if(ints.size() == 0 || next == str.length()) {
            throw new NumberFormatException("Not a valid integer range.");
          }
          // Shorter (but less tolerant) syntax: 1,..,10
          if(ints.size() == 1) {
            int start = ints.get(0);
            // Hack for: 1,..,10,20,..,100: reuse last value!
            int step = last == Integer.MAX_VALUE ? 1 : start - last;
            // Find next comma:
            next = nextSep(str, pos = next + 1);
            last = ParseUtil.parseIntBase10(str, pos, next); // Update last!
            generators.add(new LinearIntGenerator(start, step, last));
            ints.clear();
            continue;
          }
          // Longer syntax: 10,15,..,35 or 10,15,...,35 or 10,15,,35
          assert (ints.size() > 1);
          int start = ints.get(ints.size() - 2); // F
          int step = ints.get(ints.size() - 1) - start;
          ints.remove(ints.size() - 2, 2);
          // Remove additional static entries if step size is consistent:
          while(!ints.isEmpty() && ints.get(ints.size() - 1) == start - step) {
            start -= step;
            ints.remove(ints.size() - 1, 1);
          }
          // Leading elements not part of this sequence:
          if(!ints.isEmpty()) {
            generators.add(new StaticIntGenerator(ints.toArray()));
          }
          // Find next comma:
          next = nextSep(str, pos = next + 1);
          last = ParseUtil.parseIntBase10(str, pos, next); // Update last!
          generators.add(new LinearIntGenerator(start, step, last));
          ints.clear();
        }
        // Explicit syntax: 0,+=4,16
        else if(next - pos > 2 && str.charAt(pos) == '+' && str.charAt(pos + 1) == '=') {
          if(ints.size() == 0 || next == str.length()) {
            throw new NumberFormatException("Not a valid integer range.");
          }
          int start = ints.get(ints.size() - 1); //
          int step = ParseUtil.parseIntBase10(str, pos + 2, next);
          ints.remove(ints.size() - 1, 1);
          // Remove additional static entries if step size is consistent:
          while(!ints.isEmpty() && ints.get(ints.size() - 1) == start - step) {
            start -= step;
            ints.remove(ints.size() - 1, 1);
          }
          // Leading elements not part of this sequence:
          if(!ints.isEmpty()) {
            generators.add(new StaticIntGenerator(ints.toArray()));
          }
          // Find next comma:
          next = nextSep(str, pos = next + 1);
          last = ParseUtil.parseIntBase10(str, pos, next); // Update last!
          generators.add(new LinearIntGenerator(start, step, last));
          ints.clear();
        }
        // Explicit syntax: 0,+=4,16
        else if(next - pos > 2 && str.charAt(pos) == '*' && str.charAt(pos + 1) == '=') {
          if(ints.size() == 0 || next == str.length()) {
            throw new NumberFormatException("Not a valid integer range.");
          }
          int start = ints.get(ints.size() - 1); //
          int factor = ParseUtil.parseIntBase10(str, pos + 2, next);
          ints.remove(ints.size() - 1, 1);
          // Remove additional static entries if step size is consistent:
          while(ints.size() > 2 && ints.get(ints.size() - 1) * factor == start) {
            start = ints.get(ints.size() - 1);
            ints.remove(ints.size() - 1, 1);
          }
          // Leading elements not part of this sequence:
          if(!ints.isEmpty()) {
            generators.add(new StaticIntGenerator(ints.toArray()));
          }
          // Find next comma:
          next = nextSep(str, pos = next + 1);
          last = ParseUtil.parseIntBase10(str, pos, next); // Update last!
          generators.add(new ExponentialIntGenerator(start, factor, last));
          ints.clear();
        }
        else {
          // Default case: an integer
          ints.add(ParseUtil.parseIntBase10(str, pos, next));
        }
      }
      // Trailing static values.
      if(!ints.isEmpty()) {
        generators.add(new StaticIntGenerator(ints.toArray()));
      }
      return generators.size() == 1 ? generators.get(0) : new CombinedIntGenerator(generators);
    }