code: private String escape(final String string, final State inState) {
          if (string == null) { return null; }
          State state = inState;
          final int length = string.length();
          for (int index = 0; index < length; index++) {
              /* We don't do anything with the protocol separator */
              if (state == State.HOST && string.indexOf(PROTOCOL_SEPARATOR) == index) {
                  index += PROTOCOL_SEPARATOR.length();
                  continue;
              }
              final char c = string.charAt(index);
              if (HOST_SEPARATOR.matches(c) && state == State.HOST) {
                  state = State.PATH;
              }
              if (FRAG_SEPARATOR.matches(c) && state != State.FRAGMENT && state != State.QUERY_PARAM) {
                  /* Switch state - don't do anything with this character */
                  state = State.FRAGMENT;
              } else if (QUERY_SEPARATOR.matches(c) && (state == State.PATH || state == State.HOST)) {
                  /* Switch state - don't do anything with this character */
                  state = State.QUERY;
              } else {
                  final String encodeString = encodeCharAtIndex(string, index, state);
                  if (encodeString != null) {
                      /* We are supposed to encode this character - recursively call for the remainder of the string */
                      return string.substring(0, index) + encodeString + escape(string.substring(index + 1), state);
                  }
              }
          }
          return string;
      }
docs: Returns the escaped string beginning in the given state.  This function can be called recursively.