boolean validateChar(char c, String text, int caretPos) {
      // previous
      char pc = 0;
      for (int i = caretPos - 1; i >= 0; i--) {
        pc = text.charAt(i);
        if (!Character.isWhitespace(pc)) break;
      }

      boolean isCurDigit = c >= '0' && c <= '9';
      boolean isPrevDigit = pc >= '0' && pc <= '9';
      return isPrevDigit && (isCurDigit || c == '-' || c == ',')
          || isCurDigit && (pc == '-' || pc == ',' || pc == 0)
          || Character.isWhitespace(c) && pc == ',';
    }
    /** Returns the next lexical token in the document. */
    public int nextToken() {
      int c;
      fStartToken = fPos;
      while (true) {
        switch (c = read()) {
          case EOF:
            return EOF;
          case '/': // comment
            c = read();
            if (c == '/') {
              while (true) {
                c = read();
                if ((c == EOF) || (c == EOL)) {
                  unread(c);
                  return COMMENT;
                }
              }
            } else {
              unread(c);
            }
            return OTHER;
          case '\'': // char const
            character:
            for (; ; ) {
              c = read();
              switch (c) {
                case '\'':
                  return STRING;
                case EOF:
                  unread(c);
                  return STRING;
                case '\\':
                  c = read();
                  break;
              }
            }

          case '"': // string
            string:
            for (; ; ) {
              c = read();
              switch (c) {
                case '"':
                  return STRING;
                case EOF:
                  unread(c);
                  return STRING;
                case '\\':
                  c = read();
                  break;
              }
            }

          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
            do {
              c = read();
            } while (Character.isDigit((char) c));
            unread(c);
            return NUMBER;
          default:
            if (Character.isWhitespace((char) c)) {
              do {
                c = read();
              } while (Character.isWhitespace((char) c));
              unread(c);
              return WHITE;
            }
            if (Character.isJavaIdentifierStart((char) c)) {
              fBuffer.setLength(0);
              do {
                fBuffer.append((char) c);
                c = read();
              } while (Character.isJavaIdentifierPart((char) c));
              unread(c);
              Integer i = (Integer) fgKeys.get(fBuffer.toString());
              if (i != null) return i.intValue();
              return WORD;
            }
            return OTHER;
        }
      }
    }
  private static long decodeDisplayLong(String val) throws Exception {

    char[] chars = val.trim().toCharArray();

    String digits = "";
    String units = "";

    for (char c : chars) {

      if (Character.isDigit(c)) {

        if (units.length() > 0) {

          throw (new Exception("Invalid unit"));
        }

        digits += c;

      } else {

        if (digits.length() == 0) {

          throw (new Exception("Missing digits"));

        } else if (units.length() == 0 && Character.isWhitespace(c)) {

        } else {

          units += c;
        }
      }
    }

    long value = Long.parseLong(digits);

    if (units.length() == 0) {

      units = "m";
    }

    if (units.length() > 0) {

      char c = Character.toLowerCase(units.charAt(0));

      if (c == 'k') {

        value = value * 1024;

      } else if (c == 'm') {

        value = value * 1024 * 1024;

      } else if (c == 'g') {

        value = value * 1024 * 1024 * 1024;

      } else {

        throw (new Exception("Invalid size unit '" + units + "'"));
      }
    }

    return (value);
  }