"The string representation of the given [[integer]] in the 
 base given by [[radix]]. If the given integer is 
 [[negative|Integer.negative]], the string representation 
 will begin with `-`. Digits consist of decimal digits `0` 
 to `9`, together with and lowercase letters `a` to `z` for 
 bases greater than 10.
 
 For example:
 
 - `formatInteger(-46)` is `\"-46\"`
 - `formatInteger(9,2)` is `\"1001\"`
 - `formatInteger(10,8)` is `\"12\"`
 - `formatInteger(511,16)` is `\"1ff\"`
 - `formatInteger(512,32)` is `\"g0\"`"
throws (`class AssertionError`, 
        "if [[radix]] is not between [[minRadix]] and 
         [[maxRadix]]")
see (`function formatFloat`,
     `function parseInteger`)
tagged("Numbers")
shared String formatInteger(
        "The integer value to format."
        Integer integer,
        "The base, between [[minRadix]] and [[maxRadix]] 
         inclusive."
        Integer radix = 10,
        "If not `null`, `groupingSeparator` will be used to
         separate each group of three digits if `radix` is 10,
         or each group of four digits if `radix` is 2 or 16.

         `groupingSeparator` may not be '-', a digit as
         defined by the Unicode general category *Nd*, or a
         letter as defined by the Unicode general categories
         *Lu, Ll, Lt, Lm, and Lo*."
        Character? groupingSeparator = null) {

    assert (minRadix <= radix <= maxRadix);

    if (exists groupingSeparator) {
        "groupingSeparator may not be '-', a digit, or a letter."
        assert (!groupingSeparator.digit
                && !groupingSeparator.letter
                && !groupingSeparator == '-');
    }

    if (integer == 0) {
        return "0";
    }

    value groupingSize =
            if (!groupingSeparator exists)
                then 0
            else if (radix == 10)
                then 3
            else if (radix == 2 || radix == 16)
                then 4
            else 0;

    value groupingChar =
            if (exists groupingSeparator,
                groupingSize != 0)
            then groupingSeparator
            else 'X';

    variable value digitNumber = 0;
    variable {Character*} digits = {};
    variable Integer i = integer < 0 
                         then integer 
                         else -integer;
    while (i != 0) {
        Integer d = -(i % radix);
        Character c;
        if (0<=d<10) {
            c = (d+zeroInt).character;
        }
        else if (10<=d<36) {
            c = (d-10+aIntLower).character;
        }
        else {
            assert (false);
        }
        if (groupingSize != 0
                && groupingSize.divides(digitNumber++)
                && digitNumber != 1) {
            digits = digits.follow(groupingChar);
        }
        digits = digits.follow(c);
        i = (i + d) / radix;
    }
    if (integer < 0) {
        digits = digits.follow('-');
    }
    return String(digits);
}