docs: @Override
    protected char[] escape(int cp) {
      // We should never get negative values here but if we do it will throw an
      // IndexOutOfBoundsException, so at least it will get spotted.
      if (cp < safeOctets.length && safeOctets[cp]) {
        return null;
      } else if (cp == ' ' && plusForSpace) {
        return PLUS_SIGN;
      } else if (cp <= 0x7F) {
        // Single byte UTF-8 characters
        // Start with "%--" and fill in the blanks
        char[] dest = new char[3];
        dest[0] = '%';
        dest[2] = UPPER_HEX_DIGITS[cp & 0xF];
        dest[1] = UPPER_HEX_DIGITS[cp >>> 4];
        return dest;
      } else if (cp <= 0x7ff) {
        // Two byte UTF-8 characters [cp >= 0x80 && cp <= 0x7ff]
        // Start with "%--%--" and fill in the blanks
        char[] dest = new char[6];
        dest[0] = '%';
        dest[3] = '%';
        dest[5] = UPPER_HEX_DIGITS[cp & 0xF];
        cp >>>= 4;
        dest[4] = UPPER_HEX_DIGITS[0x8 | (cp & 0x3)];
        cp >>>= 2;
        dest[2] = UPPER_HEX_DIGITS[cp & 0xF];
        cp >>>= 4;
        dest[1] = UPPER_HEX_DIGITS[0xC | cp];
        return dest;
      } else if (cp <= 0xffff) {
        // Three byte UTF-8 characters [cp >= 0x800 && cp <= 0xffff]
        // Start with "%E-%--%--" and fill in the blanks
        char[] dest = new char[9];
        dest[0] = '%';
        dest[1] = 'E';
        dest[3] = '%';
        dest[6] = '%';
        dest[8] = UPPER_HEX_DIGITS[cp & 0xF];
        cp >>>= 4;
        dest[7] = UPPER_HEX_DIGITS[0x8 | (cp & 0x3)];
        cp >>>= 2;
        dest[5] = UPPER_HEX_DIGITS[cp & 0xF];
        cp >>>= 4;
        dest[4] = UPPER_HEX_DIGITS[0x8 | (cp & 0x3)];
        cp >>>= 2;
        dest[2] = UPPER_HEX_DIGITS[cp];
        return dest;
      } else if (cp <= 0x10ffff) {
        char[] dest = new char[12];
        // Four byte UTF-8 characters [cp >= 0xffff && cp <= 0x10ffff]
        // Start with "%F-%--%--%--" and fill in the blanks
        dest[0] = '%';
        dest[1] = 'F';
        dest[3] = '%';
        dest[6] = '%';
        dest[9] = '%';
        dest[11] = UPPER_HEX_DIGITS[cp & 0xF];
        cp >>>= 4;
        dest[10] = UPPER_HEX_DIGITS[0x8 | (cp & 0x3)];
        cp >>>= 2;
        dest[8] = UPPER_HEX_DIGITS[cp & 0xF];
        cp >>>= 4;
        dest[7] = UPPER_HEX_DIGITS[0x8 | (cp & 0x3)];
        cp >>>= 2;
        dest[5] = UPPER_HEX_DIGITS[cp & 0xF];
        cp >>>= 4;
        dest[4] = UPPER_HEX_DIGITS[0x8 | (cp & 0x3)];
        cp >>>= 2;
        dest[2] = UPPER_HEX_DIGITS[cp & 0x7];
        return dest;
      } else {
        // If this ever happens it is due to bug in UnicodeEscaper, not bad input.
        throw new IllegalArgumentException("Invalid unicode character value " + cp);
      }
    }