@Override
 public synchronized void configure(Binder binder) {
   System.out.println("start");
   for (ProviderMethod<?> providerMethod : getProviderMethods(binder)) {
     providerMethod.configure(binder);
   }
 }
 public List<ProviderMethod<?>> getProviderMethods(Binder binder) {
   System.out.println("end");
   List<ProviderMethod<?>> result = Lists.newArrayList();
   Multimap<Signature, Method> methodsBySignature = HashMultimap.create();
   for (Class<?> c = delegate.getClass(); c != Object.class; c = c.getSuperclass()) {
     for (Method method : c.getDeclaredMethods()) {
       // private/static methods cannot override or be overridden by other methods, so there is no
       // point in indexing them.
       // Skip synthetic methods and bridge methods since java will automatically generate
       // synthetic overrides in some cases where we don't want to generate an error (e.g.
       // increasing visibility of a subclass).
       if (((method.getModifiers() & (Modifier.PRIVATE | Modifier.STATIC)) == 0)
           && !method.isBridge()
           && !method.isSynthetic()) {
         methodsBySignature.put(new Signature(method), method);
       }
       Optional<Annotation> annotation = isProvider(binder, method);
       if (annotation.isPresent()) {
         result.add(createProviderMethod(binder, method, annotation.get()));
       }
     }
   }
   // we have found all the providers and now need to identify if any were overridden
   // In the worst case this will have O(n^2) in the number of @Provides methods, but that is only
   // assuming that every method is an override, in general it should be very quick.
   for (ProviderMethod<?> provider : result) {
     Method method = provider.getMethod();
     for (Method matchingSignature : methodsBySignature.get(new Signature(method))) {
       // matching signature is in the same class or a super class, therefore method cannot be
       // overridding it.
       if (matchingSignature.getDeclaringClass().isAssignableFrom(method.getDeclaringClass())) {
         continue;
       }
       // now we know matching signature is in a subtype of method.getDeclaringClass()
       if (overrides(matchingSignature, method)) {
         String annotationString =
             provider.getAnnotation().annotationType() == Provides.class
                 ? "@Provides"
                 : "@" + provider.getAnnotation().annotationType().getCanonicalName();
         binder.addError(
             "Overriding "
                 + annotationString
                 + " methods is not allowed."
                 + "\n\t"
                 + annotationString
                 + " method: %s\n\toverridden by: %s",
             method,
             matchingSignature);
         break;
       }
     }
   }
   return result;
 }
  private <T> ProviderMethod<T> createProviderMethod(
      Binder binder, Method method, Annotation annotation) {
    binder = binder.withSource(method);
    Errors errors = new Errors(method);

    // prepare the parameter providers
    InjectionPoint point = InjectionPoint.forMethod(method, typeLiteral);
    List<Dependency<?>> dependencies = point.getDependencies();
    List<Provider<?>> parameterProviders = Lists.newArrayList();
    for (Dependency<?> dependency : point.getDependencies()) {
      parameterProviders.add(binder.getProvider(dependency));
    }

    @SuppressWarnings("unchecked") // Define T as the method's return type.
    TypeLiteral<T> returnType = (TypeLiteral<T>) typeLiteral.getReturnType(method);
    Key<T> key = getKey(errors, returnType, method, method.getAnnotations());
    try {
      key = scanner.prepareMethod(binder, annotation, key, point);
    } catch (Throwable t) {
      binder.addError(t);
    }
    Class<? extends Annotation> scopeAnnotation =
        Annotations.findScopeAnnotation(errors, method.getAnnotations());
    for (Message message : errors.getMessages()) {
      binder.addError(message);
    }
    return ProviderMethod.create(
        key,
        method,
        delegate,
        ImmutableSet.copyOf(dependencies),
        parameterProviders,
        scopeAnnotation,
        skipFastClassGeneration,
        annotation);
  }