class Result {
    abstract @Nullable Path path();

    abstract String input();

    abstract @Nullable String output();

    boolean changed() {
      return !input().equals(output());
    }

    abstract @Nullable FormatterException exception();

    static Result create(
        @Nullable Path path,
        String input,
        @Nullable String output,
        @Nullable FormatterException exception) {
      return new AutoValue_FormatFileCallable_Result(path, input, output, exception);
    }
  }

  private final Path path;
  private final String input;
  private final CommandLineOptions parameters;
  private final JavaFormatterOptions options;

  public FormatFileCallable(
      CommandLineOptions parameters, Path path, String input, JavaFormatterOptions options) {
    this.path = path;
    this.input = input;
    this.parameters = parameters;
    this.options = options;
  }

  @Override
  public Result call() {
    try {
      if (parameters.fixImportsOnly()) {
        return Result.create(path, input, fixImports(input), /* exception= */ null);
      }

      Formatter formatter = new Formatter(options);
      String formatted = formatter.formatSource(input, characterRanges(input).asRanges());
      formatted = fixImports(formatted);
      if (parameters.reflowLongStrings()) {
        formatted = StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, formatted, formatter);
      }
      return Result.create(path, input, formatted, /* exception= */ null);
    } catch (FormatterException e) {
      return Result.create(path, input, /* output= */ null, e);
    }
  }

  private String fixImports(String input) throws FormatterException {<FILL_FUNCTION_BODY>

    if (parameters.removeUnusedImports()) {
      input = RemoveUnusedImports.removeUnusedImports(input);
    }
    if (parameters.sortImports()) {
      input = ImportOrderer.reorderImports(input, options.style());
    }
    return input;
  
<no_super_class>