throws Throwable
  public static int preg_match_all(Env env,                                   String patternString,                                   String subject,                                   @Reference Value matchRef,                                   @Optional("PREG_PATTERN_ORDER") int flags,                                   @Optional int offset)    throws Throwable  {    if (patternString.length() < 2) {      env.warning(L.l("Pattern must have at least opening and closing delimiters"));      return 0;    }    if (((flags & PREG_PATTERN_ORDER) != 0) && ((flags & PREG_SET_ORDER) != 0)) {      env.warning((L.l("Cannot combine PREG_PATTER_ORDER and PREG_SET_ORDER")));      return 0;    }    Pattern pattern = compileRegexp(patternString);    Matcher matcher = pattern.matcher(subject);    ArrayValue matches;    if (matchRef instanceof ArrayValue)      matches = (ArrayValue) matchRef;    else      matches = new ArrayValueImpl();    matches.clear();    matchRef.set(matches);    ArrayValue []matchList = new ArrayValue[matcher.groupCount() + 1];    if ((flags & PREG_PATTERN_ORDER) != 0) {      for (int j = 0; j <= matcher.groupCount(); j++) {        ArrayValue values = new ArrayValueImpl();        matches.put(values);        matchList[j] = values;      }    }    if (! (matcher.find())) {      return 0;    }    int count = 0;    do {      count++;      if ((flags & PREG_PATTERN_ORDER) != 0) {        for (int j = 0; j <= matcher.groupCount(); j++) {          ArrayValue values = matchList[j];          String groupValue = matcher.group(j);          Value result = NullValue.NULL;          if (groupValue != null) {            if ((flags & PREG_OFFSET_CAPTURE) != 0) {              result = new ArrayValueImpl();              result.put(new StringValueImpl(groupValue));              result.put(LongValue.create(matcher.start(j)));            } else {	      result = new StringValueImpl(groupValue);            }          }          values.put(result);        }      }      else if ((flags & PREG_SET_ORDER) != 0) {        ArrayValue matchResult = new ArrayValueImpl();        matches.put(matchResult);        for (int j = 0; j <= matcher.groupCount(); j++) {          String groupValue = matcher.group(j);          Value result = NullValue.NULL;          if (groupValue != null) {            if ((flags & PREG_OFFSET_CAPTURE) != 0) {              result = new ArrayValueImpl();              result.put(new StringValueImpl(groupValue));              result.put(new LongValue(matcher.start(j)));            } else {              result = new StringValueImpl(groupValue);            }          }          matchResult.put(result);        }      }      else {        throw new UnsupportedOperationException();      }    } while (matcher.find());    return count;  }