code: ImmutableMap<ExecutableElement, TypeMirror> methodReturnTypes(
        Set<ExecutableElement> methods, DeclaredType in) {
      ImmutableMap.Builder<ExecutableElement, TypeMirror> map = ImmutableMap.builder();
      Map<Name, ExecutableElement> noArgMethods = null;
      for (ExecutableElement method : methods) {
        TypeMirror returnType = null;
        try {
          TypeMirror methodMirror = typeUtils.asMemberOf(in, method);
          returnType = MoreTypes.asExecutable(methodMirror).getReturnType();
        } catch (IllegalArgumentException e) {
          if (method.getParameters().isEmpty()) {
            if (noArgMethods == null) {
              noArgMethods = noArgMethodsIn(in);
            }
            returnType = noArgMethods.get(method.getSimpleName()).getReturnType();
          }
        }
        if (returnType == null) {
          returnType = method.getReturnType();
        }
        map.put(method, returnType);
      }
      return map.build();
    }
docs: Returns a map containing the real return types of the given methods, knowing that they appear
  in the given type. This means that if the given type is say {@code StringIterator implements
  Iterator<String>} then we want the {@code next()} method to map to String, rather than the
  {@code T} that it returns as inherited from {@code Iterator<T>}. This method is in EclipseHack
  because if it weren't for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382590">this
  Eclipse bug</a> it would be trivial. Unfortunately, versions of Eclipse up to at least 4.5 have
  a bug where the {@link Types#asMemberOf} method throws IllegalArgumentException if given a
  method that is inherited from an interface. Fortunately, Eclipse's implementation of {@link
  Elements#getAllMembers} does the type substitution that {@code asMemberOf} would have done. But
  javac's implementation doesn't. So we try the way that would work if Eclipse weren't buggy, and
  only if we get IllegalArgumentException do we use {@code getAllMembers}.