throws Throwable
  private static String pregReplaceCallbackImpl(Env env,                                                String patternString,                                                Callback fun,                                                String subject,                                                long limit,                                                Value countV)    throws Throwable  {    long numberOfMatches = 0;    if (limit < 0)      limit = Long.MAX_VALUE;    Pattern pattern = compileRegexp(patternString);    Matcher matcher = pattern.matcher(subject);    StringBuilder result = new StringBuilder();    int tail = 0;    while (matcher.find() && numberOfMatches < limit) {      // Increment countV (note: if countV != null, then it should be a Var)      if ((countV != null) && (countV instanceof Var)) {        long count = ((Var) countV).getRawValue().toLong();        countV.set(new LongValue(count + 1));      }      if (tail < matcher.start())        result.append(subject.substring(tail, matcher.start()));      ArrayValue regs = new ArrayValueImpl();      for (int i = 0; i <= matcher.groupCount(); i++) {        String group = matcher.group(i);        if (group != null)          regs.put(new StringValueImpl(group));        else          regs.put(StringValue.EMPTY);      }      Value replacement = fun.eval(env, regs);      result.append(replacement);      tail = matcher.end();      numberOfMatches++;    }    if (tail < subject.length())      result.append(subject.substring(tail));    return result.toString();  }