Fix ElementSource attribution for ModuleAnnotatedMethodScanner bindings.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=86029834
diff --git a/core/src/com/google/inject/internal/ProviderMethodsModule.java b/core/src/com/google/inject/internal/ProviderMethodsModule.java
index 98eb45d..4ff3e9f 100644
--- a/core/src/com/google/inject/internal/ProviderMethodsModule.java
+++ b/core/src/com/google/inject/internal/ProviderMethodsModule.java
@@ -114,6 +114,10 @@
     return new ProviderMethodsModule(object, skipFastClassGeneration, scanner);
   }
 
+  public Module getDelegateModule() {
+    return delegate instanceof Module ? (Module) delegate : null;
+  }
+
   @Override
   public synchronized void configure(Binder binder) {
     for (ProviderMethod<?> providerMethod : getProviderMethods(binder)) {
@@ -258,7 +262,11 @@
     @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());
-    key = scanner.prepareMethod(binder, annotation, key, point);
+    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()) {
diff --git a/core/src/com/google/inject/spi/Elements.java b/core/src/com/google/inject/spi/Elements.java
index 986582e..fcd714d 100644
--- a/core/src/com/google/inject/spi/Elements.java
+++ b/core/src/com/google/inject/spi/Elements.java
@@ -242,13 +242,27 @@
     public void install(Module module) {
       if (modules.add(module)) {
         Binder binder = this;
+        boolean unwrapModuleSource = false;
         // Update the module source for the new module
         if (!(module instanceof ProviderMethodsModule)) {
           moduleSource = getModuleSource(module);
+          unwrapModuleSource = true;
+        } else {
+          // There are two reason's we'd want to get the module source in a ProviderMethodsModule.
+          // ModuleAnnotatedMethodScanner lets users scan their own modules for @Provides-like
+          // bindings.  If they install the module at a top-level, then moduleSource can be null.
+          // Also, if they pass something other than 'this' to it, we'd have the wrong source.
+          Module delegate = ((ProviderMethodsModule) module).getDelegateModule();
+          if (delegate != null
+              && (moduleSource == null
+              || !moduleSource.getModuleClassName().equals(delegate.getClass().getName()))) {
+            moduleSource = getModuleSource(delegate);
+            unwrapModuleSource = true;
+          }
         }
         if (module instanceof PrivateModule) {
           binder = binder.newPrivateBinder();
-        }      
+        }
         try {
           module.configure(binder);
         } catch (RuntimeException e) {
@@ -261,7 +275,7 @@
         }
         binder.install(ProviderMethodsModule.forModule(module));
         // We are done with this module, so undo module source change
-        if (!(module instanceof ProviderMethodsModule)) {
+        if (unwrapModuleSource) {
           moduleSource = moduleSource.getParent();
         }
       }
diff --git a/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java b/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java
index 62f8220..8e4515b 100644
--- a/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java
+++ b/core/test/com/google/inject/spi/ModuleAnnotatedMethodScannerTest.java
@@ -21,6 +21,8 @@
 import static java.lang.annotation.ElementType.METHOD;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
+import com.google.common.collect.Iterables;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
@@ -125,4 +127,64 @@
           Names.named(((Named) key.getAnnotation()).value() + "-munged"));
     }
   }
+
+  public void testFailingScanner_scannerOutsideModule() {
+    try {
+      Guice.createInjector(new FailingScanner().forModule(new SomeModule()));
+      fail();
+    } catch (CreationException expected) {
+      Message m = Iterables.getOnlyElement(expected.getErrorMessages());
+      assertEquals(
+          "An exception was caught and reported. Message: Failing in the scanner.",
+          m.getMessage());
+      assertEquals(IllegalStateException.class, m.getCause().getClass());
+      ElementSource source = (ElementSource) Iterables.getOnlyElement(m.getSources());
+      assertEquals(SomeModule.class.getName(),
+          Iterables.getOnlyElement(source.getModuleClassNames()));
+      assertEquals(String.class.getName() + " " + SomeModule.class.getName() + ".aString()",
+          source.toString());
+    }
+  }
+
+  public void testFailingScanner_scannerInModule() {
+    Module module = new AbstractModule() {
+      @Override public void configure() {
+        install(new FailingScanner().forModule(new SomeModule()));
+      }
+    };
+    try {
+      Guice.createInjector(module);
+      fail();
+    } catch (CreationException expected) {
+      Message m = Iterables.getOnlyElement(expected.getErrorMessages());
+      assertEquals(
+          "An exception was caught and reported. Message: Failing in the scanner.",
+          m.getMessage());
+      assertEquals(IllegalStateException.class, m.getCause().getClass());
+      ElementSource source = (ElementSource) Iterables.getOnlyElement(m.getSources());
+      assertEquals(ImmutableList.of(SomeModule.class.getName(), module.getClass().getName()),
+          source.getModuleClassNames());
+      assertEquals(String.class.getName() + " " + SomeModule.class.getName() + ".aString()",
+          source.toString());
+    }
+  }
+
+  public static class FailingScanner extends ModuleAnnotatedMethodScanner {
+    @Override public Set<? extends Class<? extends Annotation>> annotationClasses() {
+      return ImmutableSet.of(TestProvides.class);
+    }
+
+    @Override public <T> Key<T> prepareMethod(
+        Binder binder, Annotation rawAnnotation, Key<T> key, InjectionPoint injectionPoint) {
+      throw new IllegalStateException("Failing in the scanner.");
+    }
+  }
+
+  static class SomeModule extends AbstractModule {
+    @TestProvides String aString() {
+      return "Foo";
+    }
+
+    @Override protected void configure() {}
+  }
 }