/** @return null if fails to convert. */
  public static QName _parseQName(CharSequence text, NamespaceContext nsc) {
    int length = text.length();

    // trim whitespace
    int start = 0;
    while (start < length && WhiteSpaceProcessor.isWhiteSpace(text.charAt(start))) start++;

    int end = length;
    while (end > start && WhiteSpaceProcessor.isWhiteSpace(text.charAt(end - 1))) end--;

    if (end == start) throw new IllegalArgumentException("input is empty");

    String uri;
    String localPart;
    String prefix;

    // search ':'
    int idx = start + 1; // no point in searching the first char. that's not valid.
    while (idx < end && text.charAt(idx) != ':') idx++;

    if (idx == end) {
      uri = nsc.getNamespaceURI("");
      localPart = text.subSequence(start, end).toString();
      prefix = "";
    } else {
      // Prefix exists, check everything
      prefix = text.subSequence(start, idx).toString();
      localPart = text.subSequence(idx + 1, end).toString();
      uri = nsc.getNamespaceURI(prefix);
      // uri can never be null according to javadoc,
      // but some users reported that there are implementations that return null.
      if (uri == null || uri.length() == 0) // crap. the NamespaceContext interface is broken.
        // error: unbound prefix
        throw new IllegalArgumentException("prefix " + prefix + " is not bound to a namespace");
    }

    return new QName(uri, localPart, prefix);
  }
  public static boolean _parseBoolean(CharSequence literal) {
    int i = 0;
    int len = literal.length();
    char ch;
    do {
      ch = literal.charAt(i++);
    } while (WhiteSpaceProcessor.isWhiteSpace(ch) && i < len);

    // if we are strict about errors, check i==len. and report an error

    if (ch == 't' || ch == '1') return true;
    if (ch == 'f' || ch == '0') return false;
    return false;
  }
  /**
   * Faster but less robust String->int conversion.
   *
   * <p>Note that:
   *
   * <ol>
   *   <li>XML Schema allows '+', but {@link Integer#valueOf(String)} is not.
   *   <li>XML Schema allows leading and trailing (but not in-between) whitespaces.. {@link
   *       Integer#valueOf(String)} doesn't allow any.
   * </ol>
   */
  public static int _parseInt(CharSequence s) {
    int len = s.length();
    int sign = 1;

    int r = 0;

    for (int i = 0; i < len; i++) {
      char ch = s.charAt(i);
      if (WhiteSpaceProcessor.isWhiteSpace(ch)) {
        // skip whitespace
      } else if ('0' <= ch && ch <= '9') {
        r = r * 10 + (ch - '0');
      } else if (ch == '-') {
        sign = -1;
      } else if (ch == '+') {
        // noop
      } else throw new NumberFormatException("Not a number: " + s);
    }

    return r * sign;
  }