code: private String encodeCharAtIndex(final String string, final int index, final State state) {
          final char c = string.charAt(index);
  
          /* Special-case: spaces are "%20" when not within query string, or when doing strict mode */
          if ((SPACE.matches(c) && ((state != State.QUERY && state != State.QUERY_PARAM) || strict)) ||
              (strict && PLUS.matches(c) && state == State.QUERY)) {
              return "%20";
          }
  
          /* Check if there are two hex digits after a percent */
          if (ESCAPED.matches(c) && string.length() > index + 2 &&
              HEX.matches(string.charAt(index + 1)) && HEX.matches(string.charAt(index + 2))) {
              return null;
          }
          
          /* We got this far - so if we are an illegal character, escape it */
          if (isIllegal(c, state)) {
              try {
                  /* Special-case: asterisks are not encoded by URLEncoder.encode */
                  if (c == '*') {
                      return "%2A";
                  } else {
                      return URLEncoder.encode(Character.toString(c), "UTF-8");
                  }
              } catch (UnsupportedEncodingException e) {
                  throw new AssertionError("UTF-8 always exists, " + e.getMessage());
              }
          }
          
          /* Not illegal - so return null */
          return null;
      }
docs: Encodes the character at the given index, and returns the resulting string.  If the character does not need to
  be encoded, this function returns null