Guice Multibindings: convert multibinding anonymous providers into package-private inner classes so that @Inject methods can be referenced by generated code.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=72598956
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
index e7e9df3..fe596a5 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
@@ -376,87 +376,16 @@
     @Override public void configure(Binder binder) {
       checkConfiguration(!isInitialized(), "MapBinder was already initialized");
 
-      final ImmutableSet<Dependency<?>> dependencies
+      ImmutableSet<Dependency<?>> dependencies
           = ImmutableSet.<Dependency<?>>of(Dependency.get(entrySetBinder.getSetKey()));
 
       // Binds a Map<K, Provider<V>> from a collection of Set<Entry<K, Provider<V>>.
-      final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider = binder
+      Provider<Set<Entry<K, Provider<V>>>> entrySetProvider = binder
           .getProvider(entrySetBinder.getSetKey());
-      
+
       binder.bind(providerMapKey).toProvider(
-          new RealMapBinderProviderWithDependencies<Map<K, Provider<V>>>(mapKey) {
-        private Map<K, Provider<V>> providerMap;
+          new RealProviderMapProvider(dependencies, entrySetProvider));
 
-        @Toolable @Inject void initialize(Injector injector) {
-          RealMapBinder.this.binder = null;
-          permitDuplicates = entrySetBinder.permitsDuplicates(injector);
-
-          Map<K, Provider<V>> providerMapMutable = new LinkedHashMap<K, Provider<V>>();
-          List<Map.Entry<K, Binding<V>>> bindingsMutable = Lists.newArrayList();
-          Indexer indexer = new Indexer(injector);
-          Multimap<K, IndexedBinding> index = HashMultimap.create();
-          Set<K> duplicateKeys = null;
-          for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
-            ProviderMapEntry<K, V> providerEntry = (ProviderMapEntry<K, V>) entry;
-            Key<V> valueKey = providerEntry.getValueKey();
-            Binding<V> valueBinding = injector.getBinding(valueKey);
-            // If this isn't a dup due to an exact same binding, add it.
-            if (index.put(entry.getKey(), valueBinding.acceptTargetVisitor(indexer))) {
-              Provider<V> previous = providerMapMutable.put(entry.getKey(), entry.getValue());
-              if (previous != null && !permitDuplicates) {
-                if (duplicateKeys == null) {
-                  duplicateKeys = Sets.newHashSet();
-                }
-                duplicateKeys.add(entry.getKey());
-              }
-              bindingsMutable.add(Maps.immutableEntry(entry.getKey(), valueBinding));
-            }
-          }
-          if (duplicateKeys != null) {
-            // Must use a ListMultimap in case more than one binding has the same source
-            // and is listed multiple times.
-            Multimap<K, String> dups = newLinkedKeyArrayValueMultimap();
-            for (Map.Entry<K, Binding<V>> entry : bindingsMutable) {
-              if (duplicateKeys.contains(entry.getKey())) {
-                dups.put(entry.getKey(), "\t at " + Errors.convert(entry.getValue().getSource()));
-              }
-            }
-            StringBuilder sb = new StringBuilder("Map injection failed due to duplicated key ");
-            boolean first = true;
-            for (K key : dups.keySet()) {
-              if (first) {
-                first = false;
-                if (duplicateKeyErrorMessages.containsKey(key)) {
-                  sb.setLength(0);
-                  sb.append(duplicateKeyErrorMessages.get(key));
-                } else {
-                  sb.append("\"" + key + "\", from bindings:\n");
-                }
-              } else {
-                if (duplicateKeyErrorMessages.containsKey(key)) {
-                  sb.append("\n and " + duplicateKeyErrorMessages.get(key));
-                } else {
-                  sb.append("\n and key: \"" + key + "\", from bindings:\n");
-                }
-              }
-              Joiner.on('\n').appendTo(sb, dups.get(key)).append("\n");
-            }
-            checkConfiguration(false, sb.toString());
-          }
-
-          providerMap = ImmutableMap.copyOf(providerMapMutable);
-          mapBindings = ImmutableList.copyOf(bindingsMutable);
-        }
-
-        @Override public Map<K, Provider<V>> get() {
-          return providerMap;
-        }
-
-        @Override public Set<Dependency<?>> getDependencies() {
-          return dependencies;
-        }
-      });
-      
       // The map this exposes is internally an ImmutableMap, so it's OK to massage
       // the guice Provider to javax Provider in the value (since Guice provider
       // implements javax Provider).
@@ -464,69 +393,8 @@
       Key massagedProviderMapKey = (Key)providerMapKey;
       binder.bind(javaxProviderMapKey).to(massagedProviderMapKey);
 
-      final Provider<Map<K, Provider<V>>> mapProvider = binder.getProvider(providerMapKey);
-      binder.bind(mapKey).toProvider(new RealMapWithExtensionProvider<Map<K, V>>(mapKey) {
-        @Override public Map<K, V> get() {
-          Map<K, V> map = new LinkedHashMap<K, V>();
-          for (Entry<K, Provider<V>> entry : mapProvider.get().entrySet()) {
-            V value = entry.getValue().get();
-            K key = entry.getKey();
-            checkConfiguration(value != null,
-                "Map injection failed due to null value for key \"%s\"", key);
-            map.put(key, value);
-          }
-          return Collections.unmodifiableMap(map);
-        }
-
-        @Override public Set<Dependency<?>> getDependencies() {
-          return dependencies;
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override 
-        public <B, R> R acceptExtensionVisitor(BindingTargetVisitor<B, R> visitor,
-            ProviderInstanceBinding<? extends B> binding) {
-          if (visitor instanceof MultibindingsTargetVisitor) {
-            return ((MultibindingsTargetVisitor<Map<K, V>, R>)visitor).visit(this);
-          } else {
-            return visitor.visit(binding);
-          }
-        }
-
-        @Override public Key<Map<K, V>> getMapKey() {
-          return mapKey;
-        }
-
-        @Override public TypeLiteral<?> getKeyTypeLiteral() {
-          return keyType;
-        }
-
-        @Override public TypeLiteral<?> getValueTypeLiteral() {
-          return valueType;
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override 
-        public List<Entry<?, Binding<?>>> getEntries() {
-          if (isInitialized()) {
-            return (List)mapBindings; // safe because mapBindings is immutable
-          } else {
-            throw new UnsupportedOperationException("getElements() not supported for module bindings");
-          }
-        }
-
-        @Override public boolean permitsDuplicates() {
-          if (isInitialized()) {
-            return permitDuplicates;
-          } else {
-            throw new UnsupportedOperationException("permitsDuplicates() not supported for module bindings");
-          }
-        }
-
-        @Override public boolean containsElement(Element element) {
-          return RealMapBinder.this.containsElement(element);
-        }
-      });
+      Provider<Map<K, Provider<V>>> mapProvider = binder.getProvider(providerMapKey);
+      binder.bind(mapKey).toProvider(new RealMapProvider(dependencies, mapProvider));
     }
 
     boolean containsElement(Element element) {
@@ -574,6 +442,166 @@
       return mapKey.hashCode();
     }
 
+    final class RealProviderMapProvider
+        extends RealMapBinderProviderWithDependencies<Map<K, Provider<V>>> {
+      private final ImmutableSet<Dependency<?>> dependencies;
+      private final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider;
+      private Map<K, Provider<V>> providerMap;
+
+      private RealProviderMapProvider(
+          ImmutableSet<Dependency<?>> dependencies,
+          Provider<Set<Entry<K, Provider<V>>>> entrySetProvider) {
+        super(mapKey);
+        this.dependencies = dependencies;
+        this.entrySetProvider = entrySetProvider;
+      }
+
+      @Toolable @Inject void initialize(Injector injector) {
+        RealMapBinder.this.binder = null;
+        permitDuplicates = entrySetBinder.permitsDuplicates(injector);
+
+        Map<K, Provider<V>> providerMapMutable = new LinkedHashMap<K, Provider<V>>();
+        List<Map.Entry<K, Binding<V>>> bindingsMutable = Lists.newArrayList();
+        Indexer indexer = new Indexer(injector);
+        Multimap<K, IndexedBinding> index = HashMultimap.create();
+        Set<K> duplicateKeys = null;
+        for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
+          ProviderMapEntry<K, V> providerEntry = (ProviderMapEntry<K, V>) entry;
+          Key<V> valueKey = providerEntry.getValueKey();
+          Binding<V> valueBinding = injector.getBinding(valueKey);
+          // If this isn't a dup due to an exact same binding, add it.
+          if (index.put(entry.getKey(), valueBinding.acceptTargetVisitor(indexer))) {
+            Provider<V> previous = providerMapMutable.put(entry.getKey(), entry.getValue());
+            if (previous != null && !permitDuplicates) {
+              if (duplicateKeys == null) {
+                duplicateKeys = Sets.newHashSet();
+              }
+              duplicateKeys.add(entry.getKey());
+            }
+            bindingsMutable.add(Maps.immutableEntry(entry.getKey(), valueBinding));
+          }
+        }
+        if (duplicateKeys != null) {
+          // Must use a ListMultimap in case more than one binding has the same source
+          // and is listed multiple times.
+          Multimap<K, String> dups = newLinkedKeyArrayValueMultimap();
+          for (Map.Entry<K, Binding<V>> entry : bindingsMutable) {
+            if (duplicateKeys.contains(entry.getKey())) {
+              dups.put(entry.getKey(), "\t at " + Errors.convert(entry.getValue().getSource()));
+            }
+          }
+          StringBuilder sb = new StringBuilder("Map injection failed due to duplicated key ");
+          boolean first = true;
+          for (K key : dups.keySet()) {
+            if (first) {
+              first = false;
+              if (duplicateKeyErrorMessages.containsKey(key)) {
+                sb.setLength(0);
+                sb.append(duplicateKeyErrorMessages.get(key));
+              } else {
+                sb.append("\"" + key + "\", from bindings:\n");
+              }
+            } else {
+              if (duplicateKeyErrorMessages.containsKey(key)) {
+                sb.append("\n and " + duplicateKeyErrorMessages.get(key));
+              } else {
+                sb.append("\n and key: \"" + key + "\", from bindings:\n");
+              }
+            }
+            Joiner.on('\n').appendTo(sb, dups.get(key)).append("\n");
+          }
+          checkConfiguration(false, sb.toString());
+        }
+
+        providerMap = ImmutableMap.copyOf(providerMapMutable);
+        mapBindings = ImmutableList.copyOf(bindingsMutable);
+      }
+
+      @Override public Map<K, Provider<V>> get() {
+        return providerMap;
+      }
+
+      @Override public Set<Dependency<?>> getDependencies() {
+        return dependencies;
+      }
+    }
+
+    final class RealMapProvider extends RealMapWithExtensionProvider<Map<K, V>> {
+      private final ImmutableSet<Dependency<?>> dependencies;
+      private final Provider<Map<K, Provider<V>>> mapProvider;
+
+      private RealMapProvider(
+          ImmutableSet<Dependency<?>> dependencies,
+          Provider<Map<K, Provider<V>>> mapProvider) {
+        super(mapKey);
+        this.dependencies = dependencies;
+        this.mapProvider = mapProvider;
+      }
+
+      @Override public Map<K, V> get() {
+        Map<K, V> map = new LinkedHashMap<K, V>();
+        for (Entry<K, Provider<V>> entry : mapProvider.get().entrySet()) {
+          V value = entry.getValue().get();
+          K key = entry.getKey();
+          checkConfiguration(value != null,
+              "Map injection failed due to null value for key \"%s\"", key);
+          map.put(key, value);
+        }
+        return Collections.unmodifiableMap(map);
+      }
+
+      @Override public Set<Dependency<?>> getDependencies() {
+        return dependencies;
+      }
+
+      @SuppressWarnings("unchecked")
+      @Override
+      public <B, R> R acceptExtensionVisitor(BindingTargetVisitor<B, R> visitor,
+          ProviderInstanceBinding<? extends B> binding) {
+        if (visitor instanceof MultibindingsTargetVisitor) {
+          return ((MultibindingsTargetVisitor<Map<K, V>, R>)visitor).visit(this);
+        } else {
+          return visitor.visit(binding);
+        }
+      }
+
+      @Override public Key<Map<K, V>> getMapKey() {
+        return mapKey;
+      }
+
+      @Override public TypeLiteral<?> getKeyTypeLiteral() {
+        return keyType;
+      }
+
+      @Override public TypeLiteral<?> getValueTypeLiteral() {
+        return valueType;
+      }
+
+      @SuppressWarnings("unchecked")
+      @Override
+      public List<Entry<?, Binding<?>>> getEntries() {
+        if (isInitialized()) {
+          return (List)mapBindings; // safe because mapBindings is immutable
+        } else {
+          throw new UnsupportedOperationException(
+              "getElements() not supported for module bindings");
+        }
+      }
+
+      @Override public boolean permitsDuplicates() {
+        if (isInitialized()) {
+          return permitDuplicates;
+        } else {
+          throw new UnsupportedOperationException(
+              "permitsDuplicates() not supported for module bindings");
+        }
+      }
+
+      @Override public boolean containsElement(Element element) {
+        return RealMapBinder.this.containsElement(element);
+      }
+    }
+
     /**
      * Binds {@code Map<K, Set<V>>} and {{@code Map<K, Set<Provider<V>>>}.
      */
@@ -593,71 +621,20 @@
       }
 
       @Override public void configure(Binder binder) {
-        final ImmutableSet<Dependency<?>> dependencies
+        ImmutableSet<Dependency<?>> dependencies
             = ImmutableSet.<Dependency<?>>of(Dependency.get(entrySetKey));
 
-        final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider =
+        Provider<Set<Entry<K, Provider<V>>>> entrySetProvider =
             binder.getProvider(entrySetKey);
         // Binds a Map<K, Set<Provider<V>>> from a collection of Map<Entry<K, Provider<V>> if
         // permitDuplicates was called.
         binder.bind(providerMultimapKey).toProvider(
-            new RealMapBinderProviderWithDependencies<Map<K, Set<Provider<V>>>>(multimapKey) {
-              private Map<K, Set<Provider<V>>> providerMultimap;
+            new RealProviderMultimapProvider(dependencies, entrySetProvider));
 
-              @SuppressWarnings("unused")
-              @Inject void initialize(Injector injector) {
-                Map<K, ImmutableSet.Builder<Provider<V>>> providerMultimapMutable =
-                    new LinkedHashMap<K, ImmutableSet.Builder<Provider<V>>>();
-                for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
-                  if (!providerMultimapMutable.containsKey(entry.getKey())) {
-                    providerMultimapMutable.put(
-                        entry.getKey(), ImmutableSet.<Provider<V>>builder());
-                  }
-                  providerMultimapMutable.get(entry.getKey()).add(entry.getValue());
-                }
-
-                ImmutableMap.Builder<K, Set<Provider<V>>> providerMultimapBuilder =
-                    ImmutableMap.builder();
-                for (Entry<K, ImmutableSet.Builder<Provider<V>>> entry
-                    : providerMultimapMutable.entrySet()) {
-                  providerMultimapBuilder.put(entry.getKey(), entry.getValue().build());
-                }
-                providerMultimap = providerMultimapBuilder.build();
-              }
-
-              @Override public Map<K, Set<Provider<V>>> get() {
-                return providerMultimap;
-              }
-
-              @Override public Set<Dependency<?>> getDependencies() {
-                return dependencies;
-              }
-            });
-
-        final Provider<Map<K, Set<Provider<V>>>> multimapProvider =
+        Provider<Map<K, Set<Provider<V>>>> multimapProvider =
             binder.getProvider(providerMultimapKey);
-        binder.bind(multimapKey).toProvider(new RealMapBinderProviderWithDependencies<Map<K, Set<V>>>(multimapKey) {
-
-          @Override public Map<K, Set<V>> get() {
-            ImmutableMap.Builder<K, Set<V>> multimapBuilder = ImmutableMap.builder();
-            for (Entry<K, Set<Provider<V>>> entry : multimapProvider.get().entrySet()) {
-              K key = entry.getKey();
-              ImmutableSet.Builder<V> valuesBuilder = ImmutableSet.builder();
-              for (Provider<V> valueProvider : entry.getValue()) {
-                V value = valueProvider.get();
-                checkConfiguration(value != null,
-                    "Multimap injection failed due to null value for key \"%s\"", key);
-                valuesBuilder.add(value);
-              }
-              multimapBuilder.put(key, valuesBuilder.build());
-            }
-            return multimapBuilder.build();
-          }
-
-          @Override public Set<Dependency<?>> getDependencies() {
-            return dependencies;
-          }
-        });
+        binder.bind(multimapKey).toProvider(
+            new RealMultimapProvider(dependencies, multimapProvider));
       }
 
       @Override public int hashCode() {
@@ -668,6 +645,83 @@
         return o instanceof MultimapBinder
             && ((MultimapBinder<?, ?>) o).multimapKey.equals(multimapKey);
       }
+
+      final class RealProviderMultimapProvider
+          extends RealMapBinderProviderWithDependencies<Map<K, Set<Provider<V>>>> {
+        private final ImmutableSet<Dependency<?>> dependencies;
+        private final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider;
+        private Map<K, Set<Provider<V>>> providerMultimap;
+
+        private RealProviderMultimapProvider(ImmutableSet<Dependency<?>> dependencies,
+            Provider<Set<Entry<K, Provider<V>>>> entrySetProvider) {
+          super(multimapKey);
+          this.dependencies = dependencies;
+          this.entrySetProvider = entrySetProvider;
+        }
+
+        @SuppressWarnings("unused")
+        @Inject void initialize(Injector injector) {
+          Map<K, ImmutableSet.Builder<Provider<V>>> providerMultimapMutable =
+              new LinkedHashMap<K, ImmutableSet.Builder<Provider<V>>>();
+          for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
+            if (!providerMultimapMutable.containsKey(entry.getKey())) {
+              providerMultimapMutable.put(
+                  entry.getKey(), ImmutableSet.<Provider<V>>builder());
+            }
+            providerMultimapMutable.get(entry.getKey()).add(entry.getValue());
+          }
+
+          ImmutableMap.Builder<K, Set<Provider<V>>> providerMultimapBuilder =
+              ImmutableMap.builder();
+          for (Entry<K, ImmutableSet.Builder<Provider<V>>> entry
+              : providerMultimapMutable.entrySet()) {
+            providerMultimapBuilder.put(entry.getKey(), entry.getValue().build());
+          }
+          providerMultimap = providerMultimapBuilder.build();
+        }
+
+        @Override public Map<K, Set<Provider<V>>> get() {
+          return providerMultimap;
+        }
+
+        @Override public Set<Dependency<?>> getDependencies() {
+          return dependencies;
+        }
+      }
+
+      final class RealMultimapProvider
+          extends RealMapBinderProviderWithDependencies<Map<K, Set<V>>> {
+        private final ImmutableSet<Dependency<?>> dependencies;
+        private final Provider<Map<K, Set<Provider<V>>>> multimapProvider;
+
+        RealMultimapProvider(
+            ImmutableSet<Dependency<?>> dependencies,
+            Provider<Map<K, Set<Provider<V>>>> multimapProvider) {
+          super(multimapKey);
+          this.dependencies = dependencies;
+          this.multimapProvider = multimapProvider;
+        }
+
+        @Override public Map<K, Set<V>> get() {
+          ImmutableMap.Builder<K, Set<V>> multimapBuilder = ImmutableMap.builder();
+          for (Entry<K, Set<Provider<V>>> entry : multimapProvider.get().entrySet()) {
+            K key = entry.getKey();
+            ImmutableSet.Builder<V> valuesBuilder = ImmutableSet.builder();
+            for (Provider<V> valueProvider : entry.getValue()) {
+              V value = valueProvider.get();
+              checkConfiguration(value != null,
+                  "Multimap injection failed due to null value for key \"%s\"", key);
+              valuesBuilder.add(value);
+            }
+            multimapBuilder.put(key, valuesBuilder.build());
+          }
+          return multimapBuilder.build();
+        }
+
+        @Override public Set<Dependency<?>> getDependencies() {
+          return dependencies;
+        }
+      }
     }
 
     /**