void test(List<String> opts, Main.Result expectResult, Set<Message> expectMessages) {
    System.err.println("test: " + opts);
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    try {
      DocumentationTask t = javadoc.getTask(pw, fm, null, null, opts, files);
      boolean ok = t.call();
      pw.close();
      String out = sw.toString().replaceAll("[\r\n]+", "\n");
      if (!out.isEmpty()) System.err.println(out);
      if (ok && expectResult != Main.Result.OK) {
        error("Compilation succeeded unexpectedly");
      } else if (!ok && expectResult != Main.Result.ERROR) {
        error("Compilation failed unexpectedly");
      } else check(out, expectMessages);
    } catch (IllegalArgumentException e) {
      System.err.println(e);
      String expectOut = expectMessages.iterator().next().text;
      if (expectResult != Main.Result.CMDERR) error("unexpected exception caught");
      else if (!e.getMessage().equals(expectOut)) {
        error("unexpected exception message: " + e.getMessage() + " expected: " + expectOut);
      }
    }

    //        if (errors > 0)
    //            throw new Error("stop");
  }
  void run() throws Exception {
    javadoc = ToolProvider.getSystemDocumentationTool();
    fm = javadoc.getStandardFileManager(null, null, null);
    try {
      fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
      fm.setLocation(StandardLocation.CLASS_PATH, Collections.<File>emptyList());
      files = Arrays.asList(new TestJFO("Test.java", code));

      test(
          Collections.<String>emptyList(),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR9A, Message.DL_WRN12A));

      test(
          Arrays.asList(rawDiags),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));

      //            test(Arrays.asList("-Xdoclint:none"),
      //                    Main.Result.OK,
      //                    EnumSet.of(Message.JD_WRN10, Message.JD_WRN13));

      test(
          Arrays.asList(rawDiags, "-Xdoclint"),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));

      test(
          Arrays.asList(rawDiags, "-Xdoclint:all/public"),
          Main.Result.ERROR,
          EnumSet.of(Message.OPT_BADQUAL));

      test(
          Arrays.asList(rawDiags, "-Xdoclint:all", "-public"),
          Main.Result.OK,
          EnumSet.of(Message.DL_WRN12));

      test(
          Arrays.asList(rawDiags, "-Xdoclint:syntax"),
          Main.Result.OK,
          EnumSet.of(Message.DL_WRN12));

      test(
          Arrays.asList(rawDiags, "-private"),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR6, Message.DL_ERR9, Message.DL_WRN12));

      test(
          Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR6, Message.DL_WRN12));

      test(
          Arrays.asList(rawDiags, "-Xdoclint:reference"),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR9));

      test(
          Arrays.asList(rawDiags, "-Xdoclint:badarg"),
          Main.Result.ERROR,
          EnumSet.of(Message.OPT_BADARG));

      files =
          Arrays.asList(
              new TestJFO("p1/P1Test.java", p1Code), new TestJFO("p2/P2Test.java", p2Code));

      test(
          Arrays.asList(rawDiags),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR_P1TEST, Message.DL_ERR_P2TEST));

      test(
          Arrays.asList(rawDiags, "-Xdoclint/package:p1"),
          Main.Result.ERROR,
          EnumSet.of(Message.DL_ERR_P1TEST));

      test(
          Arrays.asList(rawDiags, "-Xdoclint/package:*p"),
          Main.Result.ERROR,
          EnumSet.of(Message.OPT_BADPACKAGEARG));

      if (errors > 0) throw new Exception(errors + " errors occurred");
    } finally {
      fm.close();
    }
  }