public boolean matches(final CharSequence search_string, final int pos) throws MatcherException {
    // checks if character parameter is matched by this character class
    char c = search_string.charAt(pos);
    boolean charClass_contains_c = contains(c);
    Stack<Boolean> expression_stack = new Stack<>();
    Boolean operand1, operand2;

    Boolean match = true;
    if ((charClass_contains_c) && (isNegated)) match = false;

    if ((!charClass_contains_c) && (!isNegated)) match = false;
    expression_stack.push(match);

    for (NestedCharClass charClass : nestedClasses)
      if (charClass.isUnion) {
        operand1 = charClass.matches(search_string, pos);
        operand2 = expression_stack.pop();
        expression_stack.push(operand1 | operand2);
      } else expression_stack.push(charClass.matches(search_string, pos));

    match = true;
    while (!expression_stack.isEmpty()) match = match & expression_stack.pop();

    return match;
  }
  public String toString() {
    StringBuffer sb = new StringBuffer("CHARCLASS:");
    sb.append((isNegated) ? " [NOT " : "[");
    sb.append(charClassStrings + " ");
    for (char[] rangeArray : rangeList) sb.append(rangeArray[0] + "-" + rangeArray[1]);

    for (NestedCharClass charClass : nestedClasses) {
      sb.append(charClass.isUnion ? " OR " : " AND ");
      sb.append(charClass.toString());
    }

    sb.append(groupID_toString() + " ");
    sb.append("] ");
    return sb.toString();
  }