@Nullable ExecutableElement methodFromSuperinterfaces(
        TypeElement in, ExecutableElement method) {
      TypeElement methodContainer = MoreElements.asType(method.getEnclosingElement());
      Preconditions.checkArgument(methodContainer.getKind().isInterface());
      TypeMirror methodContainerType = typeUtils.erasure(methodContainer.asType());
      ImmutableList<TypeElement> types = ImmutableList.of(in);
      // On the first pass through this loop, `types` is the type we're starting from,
      // which might be a class or an interface. On later passes it is a list of direct
      // superinterfaces we saw in the previous pass, but only the ones that were assignable
      // to the interface that `method` appears in.
      while (!types.isEmpty()) {
        ImmutableList.Builder<TypeElement> newTypes = ImmutableList.builder();
        for (TypeElement t : types) {
          TypeMirror candidateType = typeUtils.erasure(t.asType());
          if (typeUtils.isAssignable(candidateType, methodContainerType)) {
            ExecutableElement tMethod = methodInType(t, method);
            if (tMethod != null) {
              return tMethod;
            }
            newTypes.addAll(superinterfaces(t));
          }
          if (t.getKind().isClass()) {
            TypeElement sup = superclass(t);
            if (sup != null) {
              newTypes.add(sup);
            }
          }
        }
        types = newTypes.build();
      }
      return null;
    }
Returns the given interface method as it appears in the given type. This is the method
itself, or the nearest override in a superinterface of the given type, or null if the method
is not found in the given type or any of its transitive superinterfaces.
common/src/main/java/com/google/auto/common/Overrides.java