class RegexEvaluator {

    public void update(String regex, int flags, String replacement, String input) {
        try {
            //TODO: catch empty/null exceptions
            if (!this.regex.equals(regex) || this.flags != flags) {
                pattern = Pattern.compile(regex, flags);
                this.regex = regex;
                this.flags = flags;
                this.validRegex = true;
                this.validReplex = true;
            }
            if (pattern != null) {
                matcher = pattern.matcher(input);
                matches = matcher.matches();
                matcher.reset();
                if (isNotEmpty(replacement)) {
                    try {
                        replaceFirst = matcher.replaceFirst(replacement);
                        replaceAll = matcher.replaceAll(replacement);
                        validReplex = true;
                    } catch (IllegalArgumentException iae) {
                        validReplex = false;
                        replexReason = iae.getMessage();
                        replaceAll = "";
                        replaceFirst = "";
                    } catch (IndexOutOfBoundsException ioe) {
                        validReplex = false;
                        replexReason = ioe.getMessage();
                        replaceAll = "";
                        replaceFirst = "";
                    }
                }
                lookingAt = matcher.lookingAt();
                matcher.reset();
                find = matcher.find();
                if (find) {
                    groups = new MatcherGroup[matcher.groupCount() + 1];
                    for (int i = 0; i < matcher.groupCount() + 1; i++) {
                        groups[i] = new MatcherGroup(matcher.start(i), matcher.end(i), matcher.group(i));
                    }
                } else {
                    groups = new MatcherGroup[0];
                }
            }
        } catch (PatternSyntaxException pse) {
            this.validRegex = false;
            this.regexReason = pse.getMessage();
        }
    }

}

class RegexEvaluatorTest {

   RegexEvaluator eval;

  @Test
  public void testMultipleGroups() {

    String testInput = "Foobar Ipsum Lorem";
    eval.update("Foo(.*) (.*)", 0, "", testInput);
    assertTrue(eval.matches);
    assertTrue(eval.lookingAt);
    assertTrue(eval.find);
    assertEquals(3, eval.groups.length);
    assertEquals(testInput, eval.groups[0].group);
    assertEquals(0, eval.groups[0].start);
    assertEquals(testInput.length(), eval.groups[0].end);
    assertEquals("bar Ipsum", eval.groups[1].group);
    assertEquals(3, eval.groups[1].start);
    assertEquals(12, eval.groups[1].end);
    assertEquals("Lorem", eval.groups[2].group);
    assertEquals(13, eval.groups[2].start);
    assertEquals(testInput.length(), eval.groups[2].end);
  }

}