private Optional<Copier> getConvertingSetterFunction(
      ImmutableList<ExecutableElement> copyOfMethods,
      E propertyElement,
      ExecutableElement setter,
      TypeMirror parameterType) {
    String property = propertyElements().inverse().get(propertyElement);
    DeclaredType targetType = MoreTypes.asDeclared(rewrittenPropertyTypes.get(property).getType());
    for (ExecutableElement copyOfMethod : copyOfMethods) {
      Optional<Copier> function =
          getConvertingSetterFunction(copyOfMethod, targetType, parameterType);
      if (function.isPresent()) {
        return function;
      }
    }
    String targetTypeSimpleName = targetType.asElement().getSimpleName().toString();
    errorReporter.reportError(
        setter,
        "[%sGetVsSetOrConvert] Parameter type %s of setter method should be %s to match %s, or it"
            + " should be a type that can be passed to %s.%s to produce %s",
        autoWhat(),
        parameterType,
        targetType,
        propertyString(propertyElement),
        targetTypeSimpleName,
        copyOfMethods.get(0).getSimpleName(),
        targetType);
    return Optional.empty();
  }
Returns an {@code Optional} describing how to convert a value from the setter's parameter type
to the getter's return type using one of the given methods, or {@code Optional.empty()} if the
conversion isn't possible. An error will have been reported in the latter case.
value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifier.java