ImmutableSet<ExecutableElement> toBuilderMethods(
        Types typeUtils, TypeElement autoValueType, Set<ExecutableElement> abstractMethods) {

      List<String> builderTypeParamNames =
          builderTypeElement.getTypeParameters().stream()
              .map(e -> e.getSimpleName().toString())
              .collect(toList());

      DeclaredType autoValueTypeMirror = MoreTypes.asDeclared(autoValueType.asType());
      ImmutableSet.Builder<ExecutableElement> methods = ImmutableSet.builder();
      for (ExecutableElement method : abstractMethods) {
        if (!method.getParameters().isEmpty()) {
          continue;
        }
        ExecutableType methodMirror =
            MoreTypes.asExecutable(typeUtils.asMemberOf(autoValueTypeMirror, method));
        TypeMirror returnTypeMirror = methodMirror.getReturnType();
        if (builderTypeElement.equals(typeUtils.asElement(returnTypeMirror))) {
          methods.add(method);
          DeclaredType returnType = MoreTypes.asDeclared(returnTypeMirror);
          List<String> typeArguments =
              returnType.getTypeArguments().stream()
                  .filter(t -> t.getKind().equals(TypeKind.TYPEVAR))
                  .map(t -> typeUtils.asElement(t).getSimpleName().toString())
                  .collect(toList());
          if (!builderTypeParamNames.equals(typeArguments)) {
            errorReporter.reportError(
                method,
                "[AutoValueBuilderConverterReturn] Builder converter method should return %s%s",
                builderTypeElement,
                TypeSimplifier.actualTypeParametersString(builderTypeElement));
          }
        }
      }
      ImmutableSet<ExecutableElement> builderMethods = methods.build();
      if (builderMethods.size() > 1) {
        errorReporter.reportError(
            builderMethods.iterator().next(),
            "[AutoValueTwoBuilderConverters] There can be at most one builder converter method");
      }
      this.toBuilderMethods = builderMethods;
      return builderMethods;
    }
Finds any methods in the set that return the builder type. If the builder has type parameters
{@code <A, B>}, then the return type of the method must be {@code Builder<A, B>} with the
same parameter names. We enforce elsewhere that the names and bounds of the builder
parameters must be the same as those of the {@code @AutoValue} class. Here's a correct
example:

<pre>{@code
@AutoValue abstract class Foo<A extends Number, B> {
  abstract int someProperty();

  abstract Builder<A, B> toBuilder();

  interface Builder<A extends Number, B> {...}
}
}</pre>

<p>We currently impose that there cannot be more than one such method.
value/src/main/java/com/google/auto/value/processor/BuilderSpec.java