code: public int next(int options) {
          int c = DONE;
          isEscaped = false;
  
          for (;;) {
              c = _current();
              _advance(UTF16.getCharCount(c));
  
              if (c == SymbolTable.SYMBOL_REF && buf == null &&
                  (options & PARSE_VARIABLES) != 0 && sym != null) {
                  String name = sym.parseReference(text, pos, text.length());
                  // If name == null there was an isolated SYMBOL_REF;
                  // return it.  Caller must be prepared for this.
                  if (name == null) {
                      break;
                  }
                  bufPos = 0;
                  buf = sym.lookup(name);
                  if (buf == null) {
                      throw new IllegalArgumentException(
                                  "Undefined variable: " + name);
                  }
                  // Handle empty variable value
                  if (buf.length == 0) {
                      buf = null;
                  }
                  continue;
              }
  
              if ((options & SKIP_WHITESPACE) != 0 &&
                  PatternProps.isWhiteSpace(c)) {
                  continue;
              }
  
              if (c == '\\' && (options & PARSE_ESCAPES) != 0) {
                  int offset[] = new int[] { 0 };
                  c = Utility.unescapeAt(lookahead(), offset);
                  jumpahead(offset[0]);
                  isEscaped = true;
                  if (c < 0) {
                      throw new IllegalArgumentException("Invalid escape");
                  }
              }
  
              break;
          }
  
          return c;
      }
docs: Returns the next character using the given options, or DONE if there
  are no more characters, and advance the position to the next
  character.
  @param options one or more of the following options, bitwise-OR-ed
  together: PARSE_VARIABLES, PARSE_ESCAPES, SKIP_WHITESPACE.
  @return the current 32-bit code point, or DONE