/**
  * Construct a {@code Formatter} given Java compilation unit. Parses the code; builds a {@link
  * JavaInput} and the corresponding {@link JavaOutput}.
  *
  * @param javaInput the input, a Java compilation unit
  * @param javaOutput the {@link JavaOutput}
  * @param maxWidth the maximum formatted width
  * @param errors mutable list to receive errors
  * @param indentationMultiplier the multiplier for the unit of indent; the default is 1
  */
 static void format(
     JavaInput javaInput,
     JavaOutput javaOutput,
     int maxWidth,
     List<FormatterDiagnostic> errors,
     int indentationMultiplier) {
   ASTParser parser = ASTParser.newParser(AST.JLS8);
   parser.setSource(javaInput.getText().toCharArray());
   @SuppressWarnings("unchecked") // safe by specification
   Map<String, String> options = JavaCore.getOptions();
   JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
   parser.setCompilerOptions(options);
   CompilationUnit unit = (CompilationUnit) parser.createAST(null);
   javaInput.setCompilationUnit(unit);
   if (unit.getMessages().length > 0) {
     for (Message message : unit.getMessages()) {
       errors.add(javaInput.createDiagnostic(message.getStartPosition(), message.getMessage()));
     }
     return;
   }
   OpsBuilder builder = new OpsBuilder(javaInput, javaOutput, errors);
   // Output compilation unit.
   new JavaInputAstVisitor(builder, indentationMultiplier).visit(unit);
   builder.sync(javaInput.getText().length());
   builder.drain();
   Doc doc = new DocBuilder().withOps(builder.build()).build();
   doc.computeBreaks(javaOutput.getCommentsHelper(), maxWidth, new Doc.State(+0, 0, 0));
   doc.write(javaOutput);
   javaOutput.flush();
 }
 private static RangeSet<Integer> characterRangesToTokenRanges(
     JavaInput javaInput, List<Range<Integer>> characterRanges) throws FormatterException {
   RangeSet<Integer> tokenRangeSet = TreeRangeSet.create();
   for (Range<Integer> characterRange0 : characterRanges) {
     Range<Integer> characterRange = characterRange0.canonical(DiscreteDomain.integers());
     tokenRangeSet.add(
         javaInput.characterRangeToTokenRange(
             characterRange.lowerEndpoint(),
             characterRange.upperEndpoint() - characterRange.lowerEndpoint()));
   }
   return tokenRangeSet;
 }