Home | History | Annotate | Download | only in multibindings
      1 /**
      2  * Copyright (C) 2008 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.inject.multibindings;
     18 
     19 import static com.google.inject.Asserts.assertContains;
     20 import static com.google.inject.multibindings.Multibinder.collectionOfJavaxProvidersOf;
     21 import static com.google.inject.multibindings.SpiUtils.VisitType.BOTH;
     22 import static com.google.inject.multibindings.SpiUtils.VisitType.MODULE;
     23 import static com.google.inject.multibindings.SpiUtils.assertSetVisitor;
     24 import static com.google.inject.multibindings.SpiUtils.instance;
     25 import static com.google.inject.multibindings.SpiUtils.providerInstance;
     26 import static com.google.inject.name.Names.named;
     27 import static java.lang.annotation.RetentionPolicy.RUNTIME;
     28 
     29 import com.google.common.base.Optional;
     30 import com.google.common.base.Predicates;
     31 import com.google.common.collect.FluentIterable;
     32 import com.google.common.collect.ImmutableList;
     33 import com.google.common.collect.ImmutableMap;
     34 import com.google.common.collect.ImmutableSet;
     35 import com.google.common.collect.Iterables;
     36 import com.google.common.collect.Lists;
     37 import com.google.common.collect.Sets;
     38 import com.google.inject.AbstractModule;
     39 import com.google.inject.Binding;
     40 import com.google.inject.BindingAnnotation;
     41 import com.google.inject.CreationException;
     42 import com.google.inject.Guice;
     43 import com.google.inject.Injector;
     44 import com.google.inject.Key;
     45 import com.google.inject.Module;
     46 import com.google.inject.Provider;
     47 import com.google.inject.Provides;
     48 import com.google.inject.ProvisionException;
     49 import com.google.inject.Scopes;
     50 import com.google.inject.Stage;
     51 import com.google.inject.TypeLiteral;
     52 import com.google.inject.name.Named;
     53 import com.google.inject.name.Names;
     54 import com.google.inject.spi.Dependency;
     55 import com.google.inject.spi.Element;
     56 import com.google.inject.spi.Elements;
     57 import com.google.inject.spi.HasDependencies;
     58 import com.google.inject.spi.InstanceBinding;
     59 import com.google.inject.spi.LinkedKeyBinding;
     60 import com.google.inject.util.Modules;
     61 import com.google.inject.util.Providers;
     62 import com.google.inject.util.Types;
     63 
     64 import junit.framework.TestCase;
     65 
     66 import java.io.ByteArrayInputStream;
     67 import java.io.ByteArrayOutputStream;
     68 import java.io.IOException;
     69 import java.io.ObjectInputStream;
     70 import java.io.ObjectOutputStream;
     71 import java.lang.annotation.Annotation;
     72 import java.lang.annotation.ElementType;
     73 import java.lang.annotation.Retention;
     74 import java.lang.annotation.RetentionPolicy;
     75 import java.lang.annotation.Target;
     76 import java.lang.reflect.Method;
     77 import java.util.Collection;
     78 import java.util.Collections;
     79 import java.util.HashSet;
     80 import java.util.List;
     81 import java.util.Map;
     82 import java.util.Map.Entry;
     83 import java.util.Set;
     84 
     85 /**
     86  * @author jessewilson (at) google.com (Jesse Wilson)
     87  */
     88 public class MultibinderTest extends TestCase {
     89 
     90   final TypeLiteral<Optional<String>> optionalOfString =
     91       new TypeLiteral<Optional<String>>() {};
     92   final TypeLiteral<Map<String, String>> mapOfStringString =
     93       new TypeLiteral<Map<String, String>>() {};
     94   final TypeLiteral<Set<String>> setOfString = new TypeLiteral<Set<String>>() {};
     95   final TypeLiteral<Set<Integer>> setOfInteger = new TypeLiteral<Set<Integer>>() {};
     96   final TypeLiteral<String> stringType = TypeLiteral.get(String.class);
     97   final TypeLiteral<Integer> intType = TypeLiteral.get(Integer.class);
     98   final TypeLiteral<List<String>> listOfStrings = new TypeLiteral<List<String>>() {};
     99   final TypeLiteral<Set<List<String>>> setOfListOfStrings = new TypeLiteral<Set<List<String>>>() {};
    100   final TypeLiteral<Collection<Provider<String>>> collectionOfProvidersOfStrings =
    101       new TypeLiteral<Collection<Provider<String>>>() {};
    102 
    103   public void testMultibinderAggregatesMultipleModules() {
    104     Module abc = new AbstractModule() {
    105       @Override protected void configure() {
    106         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    107         multibinder.addBinding().toInstance("A");
    108         multibinder.addBinding().toInstance("B");
    109         multibinder.addBinding().toInstance("C");
    110       }
    111     };
    112     Module de = new AbstractModule() {
    113       @Override protected void configure() {
    114         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    115         multibinder.addBinding().toInstance("D");
    116         multibinder.addBinding().toInstance("E");
    117       }
    118     };
    119 
    120     Injector injector = Guice.createInjector(abc, de);
    121     Key<Set<String>> setKey = Key.get(setOfString);
    122     Set<String> abcde = injector.getInstance(setKey);
    123     Set<String> results = setOf("A", "B", "C", "D", "E");
    124 
    125     assertEquals(results, abcde);
    126     assertSetVisitor(setKey, stringType, setOf(abc, de), BOTH, false, 0,
    127         instance("A"), instance("B"), instance("C"), instance("D"), instance("E"));
    128   }
    129 
    130   public void testMultibinderAggregationForAnnotationInstance() {
    131     Module module = new AbstractModule() {
    132       @Override protected void configure() {
    133         Multibinder<String> multibinder
    134             = Multibinder.newSetBinder(binder(), String.class, Names.named("abc"));
    135         multibinder.addBinding().toInstance("A");
    136         multibinder.addBinding().toInstance("B");
    137 
    138         multibinder = Multibinder.newSetBinder(binder(), String.class, Names.named("abc"));
    139         multibinder.addBinding().toInstance("C");
    140       }
    141     };
    142     Injector injector = Guice.createInjector(module);
    143 
    144     Key<Set<String>> setKey = Key.get(setOfString, Names.named("abc"));
    145     Set<String> abc = injector.getInstance(setKey);
    146     Set<String> results = setOf("A", "B", "C");
    147     assertEquals(results, abc);
    148     assertSetVisitor(setKey, stringType, setOf(module), BOTH, false, 0,
    149         instance("A"), instance("B"), instance("C"));
    150   }
    151 
    152   public void testMultibinderAggregationForAnnotationType() {
    153     Module module = new AbstractModule() {
    154       @Override protected void configure() {
    155         Multibinder<String> multibinder
    156             = Multibinder.newSetBinder(binder(), String.class, Abc.class);
    157         multibinder.addBinding().toInstance("A");
    158         multibinder.addBinding().toInstance("B");
    159 
    160         multibinder = Multibinder.newSetBinder(binder(), String.class, Abc.class);
    161         multibinder.addBinding().toInstance("C");
    162       }
    163     };
    164     Injector injector = Guice.createInjector(module);
    165 
    166     Key<Set<String>> setKey = Key.get(setOfString, Abc.class);
    167     Set<String> abcde = injector.getInstance(setKey);
    168     Set<String> results = setOf("A", "B", "C");
    169     assertEquals(results, abcde);
    170     assertSetVisitor(setKey, stringType, setOf(module), BOTH, false, 0,
    171         instance("A"), instance("B"), instance("C"));
    172   }
    173 
    174   public void testMultibinderWithMultipleAnnotationValueSets() {
    175     Module module = new AbstractModule() {
    176       @Override protected void configure() {
    177         Multibinder<String> abcMultibinder
    178             = Multibinder.newSetBinder(binder(), String.class, named("abc"));
    179         abcMultibinder.addBinding().toInstance("A");
    180         abcMultibinder.addBinding().toInstance("B");
    181         abcMultibinder.addBinding().toInstance("C");
    182 
    183         Multibinder<String> deMultibinder
    184             = Multibinder.newSetBinder(binder(), String.class, named("de"));
    185         deMultibinder.addBinding().toInstance("D");
    186         deMultibinder.addBinding().toInstance("E");
    187       }
    188     };
    189     Injector injector = Guice.createInjector(module);
    190 
    191     Key<Set<String>> abcSetKey = Key.get(setOfString, named("abc"));
    192     Set<String> abc = injector.getInstance(abcSetKey);
    193     Key<Set<String>> deSetKey = Key.get(setOfString, named("de"));
    194     Set<String> de = injector.getInstance(deSetKey);
    195     Set<String> abcResults = setOf("A", "B", "C");
    196     assertEquals(abcResults, abc);
    197     Set<String> deResults = setOf("D", "E");
    198     assertEquals(deResults, de);
    199     assertSetVisitor(abcSetKey, stringType, setOf(module), BOTH, false, 1,
    200         instance("A"), instance("B"), instance("C"));
    201     assertSetVisitor(deSetKey, stringType, setOf(module), BOTH, false, 1,
    202         instance("D"), instance("E"));
    203   }
    204 
    205   public void testMultibinderWithMultipleAnnotationTypeSets() {
    206     Module module = new AbstractModule() {
    207       @Override protected void configure() {
    208         Multibinder<String> abcMultibinder
    209             = Multibinder.newSetBinder(binder(), String.class, Abc.class);
    210         abcMultibinder.addBinding().toInstance("A");
    211         abcMultibinder.addBinding().toInstance("B");
    212         abcMultibinder.addBinding().toInstance("C");
    213 
    214         Multibinder<String> deMultibinder
    215             = Multibinder.newSetBinder(binder(), String.class, De.class);
    216         deMultibinder.addBinding().toInstance("D");
    217         deMultibinder.addBinding().toInstance("E");
    218       }
    219     };
    220     Injector injector = Guice.createInjector(module);
    221 
    222     Key<Set<String>> abcSetKey = Key.get(setOfString, Abc.class);
    223     Set<String> abc = injector.getInstance(abcSetKey);
    224     Key<Set<String>> deSetKey = Key.get(setOfString, De.class);
    225     Set<String> de = injector.getInstance(deSetKey);
    226     Set<String> abcResults = setOf("A", "B", "C");
    227     assertEquals(abcResults, abc);
    228     Set<String> deResults = setOf("D", "E");
    229     assertEquals(deResults, de);
    230     assertSetVisitor(abcSetKey, stringType, setOf(module), BOTH, false, 1,
    231         instance("A"), instance("B"), instance("C"));
    232     assertSetVisitor(deSetKey, stringType, setOf(module), BOTH, false, 1,
    233         instance("D"), instance("E"));
    234   }
    235 
    236   public void testMultibinderWithMultipleSetTypes() {
    237     Module module = new AbstractModule() {
    238       @Override protected void configure() {
    239         Multibinder.newSetBinder(binder(), String.class)
    240             .addBinding().toInstance("A");
    241         Multibinder.newSetBinder(binder(), Integer.class)
    242             .addBinding().toInstance(1);
    243       }
    244     };
    245     Injector injector = Guice.createInjector(module);
    246 
    247     assertEquals(setOf("A"), injector.getInstance(Key.get(setOfString)));
    248     assertEquals(setOf(1), injector.getInstance(Key.get(setOfInteger)));
    249     assertSetVisitor(Key.get(setOfString), stringType, setOf(module), BOTH, false, 1,
    250         instance("A"));
    251     assertSetVisitor(Key.get(setOfInteger), intType, setOf(module), BOTH, false, 1,
    252         instance(1));
    253   }
    254 
    255   public void testMultibinderWithEmptySet() {
    256     Module module = new AbstractModule() {
    257       @Override protected void configure() {
    258         Multibinder.newSetBinder(binder(), String.class);
    259       }
    260     };
    261     Injector injector = Guice.createInjector(module);
    262 
    263     Set<String> set = injector.getInstance(Key.get(setOfString));
    264     assertEquals(Collections.emptySet(), set);
    265     assertSetVisitor(Key.get(setOfString), stringType,
    266         setOf(module), BOTH, false, 0);
    267   }
    268 
    269   public void testMultibinderSetIsUnmodifiable() {
    270     Injector injector = Guice.createInjector(new AbstractModule() {
    271       @Override protected void configure() {
    272         Multibinder.newSetBinder(binder(), String.class)
    273             .addBinding().toInstance("A");
    274       }
    275     });
    276 
    277     Set<String> set = injector.getInstance(Key.get(setOfString));
    278     try {
    279       set.clear();
    280       fail();
    281     } catch(UnsupportedOperationException expected) {
    282     }
    283   }
    284 
    285   public void testMultibinderSetIsSerializable() throws IOException, ClassNotFoundException {
    286     Injector injector = Guice.createInjector(new AbstractModule() {
    287       @Override protected void configure() {
    288         Multibinder.newSetBinder(binder(), String.class)
    289             .addBinding().toInstance("A");
    290       }
    291     });
    292 
    293     Set<String> set = injector.getInstance(Key.get(setOfString));
    294     ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    295     ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
    296     try {
    297       objectOutputStream.writeObject(set);
    298     } finally {
    299       objectOutputStream.close();
    300     }
    301     ObjectInputStream objectInputStream = new ObjectInputStream(
    302         new ByteArrayInputStream(byteStream.toByteArray()));
    303     try {
    304       Object setCopy = objectInputStream.readObject();
    305       assertEquals(set, setCopy);
    306     } finally {
    307       objectInputStream.close();
    308     }
    309   }
    310 
    311   public void testMultibinderSetIsLazy() {
    312     Module module = new AbstractModule() {
    313       @Override protected void configure() {
    314         Multibinder.newSetBinder(binder(), Integer.class)
    315             .addBinding().toProvider(new Provider<Integer>() {
    316           int nextValue = 1;
    317           public Integer get() {
    318             return nextValue++;
    319           }
    320         });
    321       }
    322     };
    323     Injector injector = Guice.createInjector(module);
    324 
    325     assertEquals(setOf(1), injector.getInstance(Key.get(setOfInteger)));
    326     assertEquals(setOf(2), injector.getInstance(Key.get(setOfInteger)));
    327     assertEquals(setOf(3), injector.getInstance(Key.get(setOfInteger)));
    328     assertSetVisitor(Key.get(setOfInteger), intType, setOf(module), BOTH, false, 0,
    329         providerInstance(1));
    330   }
    331 
    332   public void testMultibinderSetForbidsDuplicateElements() {
    333     Module module1 = new AbstractModule() {
    334       @Override protected void configure() {
    335         final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    336         multibinder.addBinding().toProvider(Providers.of("A"));
    337       }
    338     };
    339     Module module2 = new AbstractModule() {
    340       @Override protected void configure() {
    341         final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    342         multibinder.addBinding().toInstance("A");
    343       }
    344     };
    345     Injector injector = Guice.createInjector(module1, module2);
    346 
    347     try {
    348       injector.getInstance(Key.get(setOfString));
    349       fail();
    350     } catch (ProvisionException expected) {
    351       assertContains(expected.getMessage(),
    352           "1) Set injection failed due to duplicated element \"A\"",
    353           "Bound at " + module1.getClass().getName(),
    354           "Bound at " + module2.getClass().getName());
    355     }
    356 
    357     // But we can still visit the module!
    358     assertSetVisitor(Key.get(setOfString), stringType, setOf(module1, module2), MODULE, false, 0,
    359         instance("A"), instance("A"));
    360   }
    361 
    362   public void testMultibinderSetShowsBothElementsIfToStringDifferent() {
    363     // A simple example of a type whose toString returns more information than its equals method
    364     // considers.
    365     class ValueType {
    366       int a;
    367       int b;
    368       ValueType(int a, int b) {
    369         this.a = a;
    370         this.b = b;
    371       }
    372       @Override
    373       public boolean equals(Object obj) {
    374         return (obj instanceof ValueType) && (((ValueType) obj).a == a);
    375       }
    376       @Override
    377       public int hashCode() {
    378         return a;
    379       }
    380       @Override
    381       public String toString() {
    382         return String.format("ValueType(%d,%d)", a, b);
    383       }
    384     }
    385 
    386     Module module1 = new AbstractModule() {
    387       @Override protected void configure() {
    388         final Multibinder<ValueType> multibinder =
    389             Multibinder.newSetBinder(binder(), ValueType.class);
    390         multibinder.addBinding().toProvider(Providers.of(new ValueType(1, 2)));
    391       }
    392     };
    393     Module module2 = new AbstractModule() {
    394       @Override protected void configure() {
    395         final Multibinder<ValueType> multibinder =
    396             Multibinder.newSetBinder(binder(), ValueType.class);
    397         multibinder.addBinding().toInstance(new ValueType(1, 3));
    398       }
    399     };
    400     Injector injector = Guice.createInjector(module1, module2);
    401 
    402     TypeLiteral<ValueType> valueType = TypeLiteral.get(ValueType.class);
    403     TypeLiteral<Set<ValueType>> setOfValueType = new TypeLiteral<Set<ValueType>>() {};
    404     try {
    405       injector.getInstance(Key.get(setOfValueType));
    406       fail();
    407     } catch (ProvisionException expected) {
    408       assertContains(expected.getMessage(),
    409           "1) Set injection failed due to multiple elements comparing equal:",
    410           "\"ValueType(1,2)\"",
    411           "bound at " + module1.getClass().getName(),
    412           "\"ValueType(1,3)\"",
    413           "bound at " + module2.getClass().getName());
    414     }
    415 
    416     // But we can still visit the module!
    417     assertSetVisitor(Key.get(setOfValueType), valueType, setOf(module1, module2), MODULE, false, 0,
    418         instance(new ValueType(1, 2)), instance(new ValueType(1, 3)));
    419   }
    420 
    421   public void testMultibinderSetPermitDuplicateElements() {
    422     Module ab = new AbstractModule() {
    423       @Override protected void configure() {
    424         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    425         multibinder.addBinding().toInstance("A");
    426         multibinder.addBinding().toInstance("B");
    427       }
    428     };
    429     Module bc = new AbstractModule() {
    430       @Override protected void configure() {
    431         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    432         multibinder.permitDuplicates();
    433         multibinder.addBinding().toInstance("B");
    434         multibinder.addBinding().toInstance("C");
    435       }
    436     };
    437     Injector injector = Guice.createInjector(ab, bc);
    438 
    439     assertEquals(setOf("A", "B", "C"), injector.getInstance(Key.get(setOfString)));
    440     assertSetVisitor(Key.get(setOfString), stringType, setOf(ab, bc), BOTH, true, 0,
    441         instance("A"), instance("B"), instance("C"));
    442   }
    443 
    444   public void testMultibinderSetPermitDuplicateCallsToPermitDuplicates() {
    445     Module ab = new AbstractModule() {
    446       @Override protected void configure() {
    447         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    448         multibinder.permitDuplicates();
    449         multibinder.addBinding().toInstance("A");
    450         multibinder.addBinding().toInstance("B");
    451       }
    452     };
    453     Module bc = new AbstractModule() {
    454       @Override protected void configure() {
    455         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    456         multibinder.permitDuplicates();
    457         multibinder.addBinding().toInstance("B");
    458         multibinder.addBinding().toInstance("C");
    459       }
    460     };
    461     Injector injector = Guice.createInjector(ab, bc);
    462 
    463     assertEquals(setOf("A", "B", "C"), injector.getInstance(Key.get(setOfString)));
    464     assertSetVisitor(Key.get(setOfString), stringType, setOf(ab, bc), BOTH, true, 0,
    465         instance("A"), instance("B"), instance("C"));
    466   }
    467 
    468   public void testMultibinderSetForbidsNullElements() {
    469     Module m = new AbstractModule() {
    470       @Override protected void configure() {
    471         Multibinder.newSetBinder(binder(), String.class)
    472             .addBinding().toProvider(Providers.<String>of(null));
    473       }
    474     };
    475     Injector injector = Guice.createInjector(m);
    476 
    477     try {
    478       injector.getInstance(Key.get(setOfString));
    479       fail();
    480     } catch(ProvisionException expected) {
    481       assertContains(expected.getMessage(),
    482           "1) Set injection failed due to null element bound at: "
    483           + m.getClass().getName() + ".configure(");
    484     }
    485   }
    486 
    487   public void testSourceLinesInMultibindings() {
    488     try {
    489       Guice.createInjector(new AbstractModule() {
    490         @Override protected void configure() {
    491           Multibinder.newSetBinder(binder(), Integer.class).addBinding();
    492         }
    493       });
    494       fail();
    495     } catch (CreationException expected) {
    496       assertContains(expected.getMessage(), "No implementation for java.lang.Integer",
    497           "at " + getClass().getName());
    498     }
    499   }
    500 
    501   /**
    502    * We just want to make sure that multibinder's binding depends on each of its values. We don't
    503    * really care about the underlying structure of those bindings, which are implementation details.
    504    */
    505   public void testMultibinderDependencies() {
    506     Injector injector = Guice.createInjector(new AbstractModule() {
    507       @Override protected void configure() {
    508         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    509         multibinder.addBinding().toInstance("A");
    510         multibinder.addBinding().to(Key.get(String.class, Names.named("b")));
    511 
    512         bindConstant().annotatedWith(Names.named("b")).to("B");
    513       }
    514     });
    515 
    516     Binding<Set<String>> binding = injector.getBinding(new Key<Set<String>>() {});
    517     HasDependencies withDependencies = (HasDependencies) binding;
    518     Set<String> elements = Sets.newHashSet();
    519     for (Dependency<?> dependency : withDependencies.getDependencies()) {
    520       elements.add((String) injector.getInstance(dependency.getKey()));
    521     }
    522     assertEquals(ImmutableSet.of("A", "B"), elements);
    523   }
    524 
    525   /**
    526    * We just want to make sure that multibinder's binding depends on each of its values. We don't
    527    * really care about the underlying structure of those bindings, which are implementation details.
    528    */
    529   public void testMultibinderDependenciesInToolStage() {
    530     Injector injector = Guice.createInjector(Stage.TOOL, new AbstractModule() {
    531       @Override protected void configure() {
    532         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    533         multibinder.addBinding().toInstance("A");
    534         multibinder.addBinding().to(Key.get(String.class, Names.named("b")));
    535 
    536         bindConstant().annotatedWith(Names.named("b")).to("B");
    537       }
    538     });
    539 
    540     Binding<Set<String>> binding = injector.getBinding(new Key<Set<String>>() {});
    541     HasDependencies withDependencies = (HasDependencies) binding;
    542     InstanceBinding<?> instanceBinding = null;
    543     LinkedKeyBinding<?> linkedBinding = null;
    544     // The non-tool stage test can test this by calling injector.getInstance to ensure
    545     // the right values are returned -- in tool stage we can't do that.  It's also a
    546     // little difficult to validate the dependencies & bindings, because they're
    547     // bindings created internally within Multibinder.
    548     // To workaround this, we just validate that the dependencies lookup to a single
    549     // InstanceBinding whose value is "A" and another LinkedBinding whose target is
    550     // the Key of @Named("b") String=B
    551     for (Dependency<?> dependency : withDependencies.getDependencies()) {
    552       Binding<?> b = injector.getBinding(dependency.getKey());
    553       if(b instanceof InstanceBinding) {
    554         if(instanceBinding != null) {
    555           fail("Already have an instance binding of: " + instanceBinding + ", and now want to add: " + b);
    556         } else {
    557           instanceBinding = (InstanceBinding)b;
    558         }
    559       } else if(b instanceof LinkedKeyBinding) {
    560         if(linkedBinding != null) {
    561           fail("Already have a linked binding of: " + linkedBinding + ", and now want to add: " + b);
    562         } else {
    563           linkedBinding = (LinkedKeyBinding)b;
    564         }
    565       } else {
    566         fail("Unexpected dependency of: " + dependency);
    567       }
    568     }
    569 
    570     assertNotNull(instanceBinding);
    571     assertNotNull(linkedBinding);
    572 
    573     assertEquals("A", instanceBinding.getInstance());
    574     assertEquals(Key.get(String.class, Names.named("b")), linkedBinding.getLinkedKey());
    575   }
    576 
    577   /**
    578    * Our implementation maintains order, but doesn't guarantee it in the API spec.
    579    * TODO: specify the iteration order?
    580    */
    581   public void testBindOrderEqualsIterationOrder() {
    582     Injector injector = Guice.createInjector(
    583         new AbstractModule() {
    584           @Override protected void configure() {
    585             Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    586             multibinder.addBinding().toInstance("leonardo");
    587             multibinder.addBinding().toInstance("donatello");
    588             install(new AbstractModule() {
    589               @Override protected void configure() {
    590                 Multibinder.newSetBinder(binder(), String.class)
    591                     .addBinding().toInstance("michaelangelo");
    592               }
    593             });
    594           }
    595         },
    596         new AbstractModule() {
    597           @Override protected void configure() {
    598             Multibinder.newSetBinder(binder(), String.class).addBinding().toInstance("raphael");
    599           }
    600         });
    601 
    602     List<String> inOrder = ImmutableList.copyOf(injector.getInstance(Key.get(setOfString)));
    603     assertEquals(ImmutableList.of("leonardo", "donatello", "michaelangelo", "raphael"), inOrder);
    604   }
    605 
    606   @Retention(RUNTIME) @BindingAnnotation
    607   @interface Abc {}
    608 
    609   @Retention(RUNTIME) @BindingAnnotation
    610   @interface De {}
    611 
    612   private <T> Set<T> setOf(T... elements) {
    613     Set<T> result = Sets.newHashSet();
    614     Collections.addAll(result, elements);
    615     return result;
    616   }
    617 
    618   /**
    619    * With overrides, we should get the union of all multibindings.
    620    */
    621   public void testModuleOverrideAndMultibindings() {
    622     Module ab = new AbstractModule() {
    623       @Override protected void configure() {
    624         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    625         multibinder.addBinding().toInstance("A");
    626         multibinder.addBinding().toInstance("B");
    627       }
    628     };
    629     Module cd = new AbstractModule() {
    630       @Override protected void configure() {
    631         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    632         multibinder.addBinding().toInstance("C");
    633         multibinder.addBinding().toInstance("D");
    634       }
    635     };
    636     Module ef = new AbstractModule() {
    637       @Override protected void configure() {
    638         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    639         multibinder.addBinding().toInstance("E");
    640         multibinder.addBinding().toInstance("F");
    641       }
    642     };
    643 
    644     Module abcd = Modules.override(ab).with(cd);
    645     Injector injector = Guice.createInjector(abcd, ef);
    646     assertEquals(ImmutableSet.of("A", "B", "C", "D", "E", "F"),
    647         injector.getInstance(Key.get(setOfString)));
    648 
    649     assertSetVisitor(Key.get(setOfString), stringType, setOf(abcd, ef), BOTH, false, 0,
    650         instance("A"), instance("B"), instance("C"), instance("D"), instance("E"), instance("F"));
    651   }
    652 
    653   /**
    654    * With overrides, we should get the union of all multibindings.
    655    */
    656   public void testModuleOverrideAndMultibindingsWithPermitDuplicates() {
    657     Module abc = new AbstractModule() {
    658       @Override protected void configure() {
    659         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    660         multibinder.addBinding().toInstance("A");
    661         multibinder.addBinding().toInstance("B");
    662         multibinder.addBinding().toInstance("C");
    663         multibinder.permitDuplicates();
    664       }
    665     };
    666     Module cd = new AbstractModule() {
    667       @Override protected void configure() {
    668         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    669         multibinder.addBinding().toInstance("C");
    670         multibinder.addBinding().toInstance("D");
    671         multibinder.permitDuplicates();
    672       }
    673     };
    674     Module ef = new AbstractModule() {
    675       @Override protected void configure() {
    676         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    677         multibinder.addBinding().toInstance("E");
    678         multibinder.addBinding().toInstance("F");
    679         multibinder.permitDuplicates();
    680       }
    681     };
    682 
    683     Module abcd = Modules.override(abc).with(cd);
    684     Injector injector = Guice.createInjector(abcd, ef);
    685     assertEquals(ImmutableSet.of("A", "B", "C", "D", "E", "F"),
    686         injector.getInstance(Key.get(setOfString)));
    687 
    688     assertSetVisitor(Key.get(setOfString), stringType, setOf(abcd, ef), BOTH, true, 0,
    689         instance("A"), instance("B"), instance("C"), instance("D"), instance("E"), instance("F"));
    690   }
    691 
    692   /**
    693    * Doubly-installed modules should not conflict, even when one is overridden.
    694    */
    695   public void testModuleOverrideRepeatedInstallsAndMultibindings_toInstance() {
    696     Module ab = new AbstractModule() {
    697       @Override protected void configure() {
    698         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    699         multibinder.addBinding().toInstance("A");
    700         multibinder.addBinding().toInstance("B");
    701       }
    702     };
    703 
    704     // Guice guarantees this assertion, as the same module cannot be installed twice.
    705     assertEquals(ImmutableSet.of("A", "B"),
    706         Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
    707 
    708     // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
    709     Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
    710     assertEquals(ImmutableSet.of("A", "B"),
    711         injector.getInstance(Key.get(setOfString)));
    712   }
    713 
    714   public void testModuleOverrideRepeatedInstallsAndMultibindings_toKey() {
    715     Module ab = new AbstractModule() {
    716       @Override protected void configure() {
    717         Key<String> aKey = Key.get(String.class, Names.named("A_string"));
    718         Key<String> bKey = Key.get(String.class, Names.named("B_string"));
    719         bind(aKey).toInstance("A");
    720         bind(bKey).toInstance("B");
    721 
    722         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    723         multibinder.addBinding().to(aKey);
    724         multibinder.addBinding().to(bKey);
    725       }
    726     };
    727 
    728     // Guice guarantees this assertion, as the same module cannot be installed twice.
    729     assertEquals(ImmutableSet.of("A", "B"),
    730         Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
    731 
    732     // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
    733     Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
    734     assertEquals(ImmutableSet.of("A", "B"),
    735         injector.getInstance(Key.get(setOfString)));
    736   }
    737 
    738   public void testModuleOverrideRepeatedInstallsAndMultibindings_toProviderInstance() {
    739     Module ab = new AbstractModule() {
    740       @Override protected void configure() {
    741         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    742         multibinder.addBinding().toProvider(Providers.of("A"));
    743         multibinder.addBinding().toProvider(Providers.of("B"));
    744       }
    745     };
    746 
    747     // Guice guarantees this assertion, as the same module cannot be installed twice.
    748     assertEquals(ImmutableSet.of("A", "B"),
    749         Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
    750 
    751     // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
    752     Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
    753     assertEquals(ImmutableSet.of("A", "B"),
    754         injector.getInstance(Key.get(setOfString)));
    755   }
    756 
    757   private static class AStringProvider implements Provider<String> {
    758     public String get() {
    759       return "A";
    760     }
    761   }
    762 
    763   private static class BStringProvider implements Provider<String> {
    764     public String get() {
    765       return "B";
    766     }
    767   }
    768 
    769   public void testModuleOverrideRepeatedInstallsAndMultibindings_toProviderKey() {
    770     Module ab = new AbstractModule() {
    771       @Override protected void configure() {
    772         Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
    773         multibinder.addBinding().toProvider(Key.get(AStringProvider.class));
    774         multibinder.addBinding().toProvider(Key.get(BStringProvider.class));
    775       }
    776     };
    777 
    778     // Guice guarantees this assertion, as the same module cannot be installed twice.
    779     assertEquals(ImmutableSet.of("A", "B"),
    780         Guice.createInjector(ab, ab).getInstance(Key.get(setOfString)));
    781 
    782     // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
    783     Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
    784     assertEquals(ImmutableSet.of("A", "B"),
    785         injector.getInstance(Key.get(setOfString)));
    786   }
    787 
    788   private static class StringGrabber {
    789     private final String string;
    790 
    791     @SuppressWarnings("unused")  // Found by reflection
    792     public StringGrabber(@Named("A_string") String string) {
    793       this.string = string;
    794     }
    795 
    796     @SuppressWarnings("unused")  // Found by reflection
    797     public StringGrabber(@Named("B_string") String string, int unused) {
    798       this.string = string;
    799     }
    800 
    801     @Override
    802     public int hashCode() {
    803       return string.hashCode();
    804     }
    805 
    806     @Override
    807     public boolean equals(Object obj) {
    808       return (obj instanceof StringGrabber) && ((StringGrabber) obj).string.equals(string);
    809     }
    810 
    811     @Override
    812     public String toString() {
    813       return "StringGrabber(" + string + ")";
    814     }
    815 
    816     static Set<String> values(Iterable<StringGrabber> grabbers) {
    817       Set<String> result = new HashSet<String>();
    818       for (StringGrabber grabber : grabbers) {
    819         result.add(grabber.string);
    820       }
    821       return result;
    822     }
    823   }
    824 
    825   public void testModuleOverrideRepeatedInstallsAndMultibindings_toConstructor() {
    826     TypeLiteral<Set<StringGrabber>> setOfStringGrabber = new TypeLiteral<Set<StringGrabber>>() {};
    827     Module ab = new AbstractModule() {
    828       @Override protected void configure() {
    829         Key<String> aKey = Key.get(String.class, Names.named("A_string"));
    830         Key<String> bKey = Key.get(String.class, Names.named("B_string"));
    831         bind(aKey).toInstance("A");
    832         bind(bKey).toInstance("B");
    833         bind(Integer.class).toInstance(0);  // used to disambiguate constructors
    834 
    835         Multibinder<StringGrabber> multibinder =
    836             Multibinder.newSetBinder(binder(), StringGrabber.class);
    837         try {
    838           multibinder.addBinding().toConstructor(
    839               StringGrabber.class.getConstructor(String.class));
    840           multibinder.addBinding().toConstructor(
    841               StringGrabber.class.getConstructor(String.class, int.class));
    842         } catch (NoSuchMethodException e) {
    843           fail("No such method: " + e.getMessage());
    844         }
    845       }
    846     };
    847 
    848     // Guice guarantees this assertion, as the same module cannot be installed twice.
    849     assertEquals(ImmutableSet.of("A", "B"),
    850         StringGrabber.values(
    851             Guice.createInjector(ab, ab).getInstance(Key.get(setOfStringGrabber))));
    852 
    853     // Guice will only guarantee this assertion if Multibinder ensures the bindings match.
    854     Injector injector = Guice.createInjector(ab, Modules.override(ab).with(ab));
    855     assertEquals(ImmutableSet.of("A", "B"),
    856         StringGrabber.values(injector.getInstance(Key.get(setOfStringGrabber))));
    857   }
    858 
    859   /**
    860    * Unscoped bindings should not conflict, whether they were bound with no explicit scope, or
    861    * explicitly bound in {@link Scopes#NO_SCOPE}.
    862    */
    863   public void testDuplicateUnscopedBindings() {
    864     Module singleBinding = new AbstractModule() {
    865       @Override protected void configure() {
    866         bind(Integer.class).to(Key.get(Integer.class, named("A")));
    867         bind(Integer.class).to(Key.get(Integer.class, named("A"))).in(Scopes.NO_SCOPE);
    868       }
    869 
    870       @Provides @Named("A")
    871       int provideInteger() {
    872         return 5;
    873       }
    874     };
    875     Module multibinding = new AbstractModule() {
    876       @Override protected void configure() {
    877         Multibinder<Integer> multibinder = Multibinder.newSetBinder(binder(), Integer.class);
    878         multibinder.addBinding().to(Key.get(Integer.class, named("A")));
    879         multibinder.addBinding().to(Key.get(Integer.class, named("A"))).in(Scopes.NO_SCOPE);
    880       }
    881     };
    882 
    883     assertEquals(5,
    884         (int) Guice.createInjector(singleBinding).getInstance(Integer.class));
    885     assertEquals(ImmutableSet.of(5),
    886         Guice.createInjector(singleBinding, multibinding).getInstance(Key.get(setOfInteger)));
    887   }
    888 
    889   /**
    890    * Ensure key hash codes are fixed at injection time, not binding time.
    891    */
    892   public void testKeyHashCodesFixedAtInjectionTime() {
    893     Module ab = new AbstractModule() {
    894       @Override protected void configure() {
    895         Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
    896         List<String> list = Lists.newArrayList();
    897         multibinder.addBinding().toInstance(list);
    898         list.add("A");
    899         list.add("B");
    900       }
    901     };
    902 
    903     Injector injector = Guice.createInjector(ab);
    904     for (Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
    905       Key<?> bindingKey = entry.getKey();
    906       Key<?> clonedKey;
    907       if (bindingKey.getAnnotation() != null) {
    908         clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotation());
    909       } else if (bindingKey.getAnnotationType() != null) {
    910         clonedKey = Key.get(bindingKey.getTypeLiteral(), bindingKey.getAnnotationType());
    911       } else {
    912         clonedKey = Key.get(bindingKey.getTypeLiteral());
    913       }
    914       assertEquals(bindingKey, clonedKey);
    915       assertEquals("Incorrect hashcode for " + bindingKey + " -> " + entry.getValue(),
    916           bindingKey.hashCode(), clonedKey.hashCode());
    917     }
    918   }
    919 
    920   /**
    921    * Ensure bindings do not rehash their keys once returned from {@link Elements#getElements}.
    922    */
    923   public void testBindingKeysFixedOnReturnFromGetElements() {
    924     final List<String> list = Lists.newArrayList();
    925     Module ab = new AbstractModule() {
    926       @Override protected void configure() {
    927         Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
    928         multibinder.addBinding().toInstance(list);
    929         list.add("A");
    930         list.add("B");
    931       }
    932     };
    933 
    934     InstanceBinding<?> binding = Iterables.getOnlyElement(
    935         Iterables.filter(Elements.getElements(ab), InstanceBinding.class));
    936     Key<?> keyBefore = binding.getKey();
    937     assertEquals(listOfStrings, keyBefore.getTypeLiteral());
    938 
    939     list.add("C");
    940     Key<?> keyAfter = binding.getKey();
    941     assertSame(keyBefore, keyAfter);
    942   }
    943 
    944   /*
    945    * Verify through gratuitous mutation that key hashCode snapshots and whatnot happens at the right
    946    * times, by binding two lists that are different at injector creation, but compare equal when the
    947    * module is configured *and* when the set is instantiated.
    948    */
    949   public void testConcurrentMutation_bindingsDiffentAtInjectorCreation() {
    950     // We initially bind two equal lists
    951     final List<String> list1 = Lists.newArrayList();
    952     final List<String> list2 = Lists.newArrayList();
    953     Module module = new AbstractModule() {
    954       @Override protected void configure() {
    955         Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
    956         multibinder.addBinding().toInstance(list1);
    957         multibinder.addBinding().toInstance(list2);
    958       }
    959     };
    960     List<Element> elements = Elements.getElements(module);
    961 
    962     // Now we change the lists so they no longer match, and create the injector.
    963     list1.add("A");
    964     list2.add("B");
    965     Injector injector = Guice.createInjector(Elements.getModule(elements));
    966 
    967     // Now we change the lists so they compare equal again, and create the set.
    968     list1.add(1, "B");
    969     list2.add(0, "A");
    970     try {
    971       injector.getInstance(Key.get(setOfListOfStrings));
    972       fail();
    973     } catch (ProvisionException e) {
    974       assertEquals(1, e.getErrorMessages().size());
    975       assertContains(
    976           Iterables.getOnlyElement(e.getErrorMessages()).getMessage().toString(),
    977           "Set injection failed due to duplicated element \"[A, B]\"");
    978     }
    979 
    980     // Finally, we change the lists again so they are once more different, and ensure the set
    981     // contains both.
    982     list1.remove("A");
    983     list2.remove("B");
    984     Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings));
    985     assertEquals(ImmutableSet.of(ImmutableList.of("A"), ImmutableList.of("B")), set);
    986   }
    987 
    988   /*
    989    * Verify through gratuitous mutation that key hashCode snapshots and whatnot happen at the right
    990    * times, by binding two lists that compare equal at injector creation, but are different when the
    991    * module is configured *and* when the set is instantiated.
    992    */
    993   public void testConcurrentMutation_bindingsSameAtInjectorCreation() {
    994     // We initially bind two distinct lists
    995     final List<String> list1 = Lists.newArrayList("A");
    996     final List<String> list2 = Lists.newArrayList("B");
    997     Module module = new AbstractModule() {
    998       @Override protected void configure() {
    999         Multibinder<List<String>> multibinder = Multibinder.newSetBinder(binder(), listOfStrings);
   1000         multibinder.addBinding().toInstance(list1);
   1001         multibinder.addBinding().toInstance(list2);
   1002       }
   1003     };
   1004     List<Element> elements = Elements.getElements(module);
   1005 
   1006     // Now we change the lists so they compare equal, and create the injector.
   1007     list1.add(1, "B");
   1008     list2.add(0, "A");
   1009     Injector injector = Guice.createInjector(Elements.getModule(elements));
   1010 
   1011     // Now we change the lists again so they are once more different, and create the set.
   1012     list1.remove("A");
   1013     list2.remove("B");
   1014     Set<List<String>> set = injector.getInstance(Key.get(setOfListOfStrings));
   1015 
   1016     // The set will contain just one of the two lists.
   1017     // (In fact, it will be the first one we bound, but we don't promise that, so we won't test it.)
   1018     assertTrue(ImmutableSet.of(ImmutableList.of("A")).equals(set)
   1019         || ImmutableSet.of(ImmutableList.of("B")).equals(set));
   1020   }
   1021 
   1022   @BindingAnnotation
   1023   @Retention(RetentionPolicy.RUNTIME)
   1024   @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
   1025   private static @interface Marker {}
   1026 
   1027   @Marker
   1028   public void testMultibinderMatching() throws Exception {
   1029     Method m = MultibinderTest.class.getDeclaredMethod("testMultibinderMatching");
   1030     assertNotNull(m);
   1031     final Annotation marker = m.getAnnotation(Marker.class);
   1032     Injector injector = Guice.createInjector(new AbstractModule() {
   1033       @Override public void configure() {
   1034         Multibinder<Integer> mb1 = Multibinder.newSetBinder(binder(), Integer.class, Marker.class);
   1035         Multibinder<Integer> mb2 = Multibinder.newSetBinder(binder(), Integer.class, marker);
   1036         mb1.addBinding().toInstance(1);
   1037         mb2.addBinding().toInstance(2);
   1038 
   1039         // This assures us that the two binders are equivalent, so we expect the instance added to
   1040         // each to have been added to one set.
   1041         assertEquals(mb1, mb2);
   1042       }
   1043     });
   1044     TypeLiteral<Set<Integer>> t = new TypeLiteral<Set<Integer>>() {};
   1045     Set<Integer> s1 = injector.getInstance(Key.get(t, Marker.class));
   1046     Set<Integer> s2 = injector.getInstance(Key.get(t, marker));
   1047 
   1048     // This assures us that the two sets are in fact equal.  They may not be same set (as in Java
   1049     // object identical), but we shouldn't expect that, since probably Guice creates the set each
   1050     // time in case the elements are dependent on scope.
   1051     assertEquals(s1, s2);
   1052 
   1053     // This ensures that MultiBinder is internally using the correct set name --
   1054     // making sure that instances of marker annotations have the same set name as
   1055     // MarkerAnnotation.class.
   1056     Set<Integer> expected = new HashSet<Integer>();
   1057     expected.add(1);
   1058     expected.add(2);
   1059     assertEquals(expected, s1);
   1060   }
   1061 
   1062   // See issue 670
   1063   public void testSetAndMapValueAreDistinct() {
   1064     Injector injector = Guice.createInjector(new AbstractModule() {
   1065       @Override protected void configure() {
   1066         Multibinder.newSetBinder(binder(), String.class)
   1067             .addBinding().toInstance("A");
   1068 
   1069         MapBinder.newMapBinder(binder(), String.class, String.class)
   1070             .addBinding("B").toInstance("b");
   1071 
   1072         OptionalBinder.newOptionalBinder(binder(), String.class)
   1073             .setDefault().toInstance("C");
   1074         OptionalBinder.newOptionalBinder(binder(), String.class)
   1075             .setBinding().toInstance("D");
   1076       }
   1077     });
   1078 
   1079     assertEquals(ImmutableSet.of("A"), injector.getInstance(Key.get(setOfString)));
   1080     assertEquals(ImmutableMap.of("B", "b"), injector.getInstance(Key.get(mapOfStringString)));
   1081     assertEquals(Optional.of("D"), injector.getInstance(Key.get(optionalOfString)));
   1082   }
   1083 
   1084   // See issue 670
   1085   public void testSetAndMapValueAreDistinctInSpi() {
   1086     Injector injector = Guice.createInjector(new AbstractModule() {
   1087       @Override protected void configure() {
   1088         Multibinder.newSetBinder(binder(), String.class)
   1089             .addBinding().toInstance("A");
   1090 
   1091         MapBinder.newMapBinder(binder(), String.class, String.class)
   1092             .addBinding("B").toInstance("b");
   1093 
   1094         OptionalBinder.newOptionalBinder(binder(), String.class)
   1095             .setDefault().toInstance("C");
   1096       }
   1097     });
   1098     Collector collector = new Collector();
   1099     Binding<Map<String, String>> mapbinding = injector.getBinding(Key.get(mapOfStringString));
   1100     mapbinding.acceptTargetVisitor(collector);
   1101     assertNotNull(collector.mapbinding);
   1102 
   1103     Binding<Set<String>> setbinding = injector.getBinding(Key.get(setOfString));
   1104     setbinding.acceptTargetVisitor(collector);
   1105     assertNotNull(collector.setbinding);
   1106 
   1107     Binding<Optional<String>> optionalbinding = injector.getBinding(Key.get(optionalOfString));
   1108     optionalbinding.acceptTargetVisitor(collector);
   1109     assertNotNull(collector.optionalbinding);
   1110 
   1111     // There should only be three instance bindings for string types
   1112     // (but because of the OptionalBinder, there's 2 ProviderInstanceBindings also).
   1113     // We also know the InstanceBindings will be in the order: A, b, C because that's
   1114     // how we bound them, and binding order is preserved.
   1115     List<Binding<String>> bindings = FluentIterable.from(injector.findBindingsByType(stringType))
   1116         .filter(Predicates.instanceOf(InstanceBinding.class))
   1117         .toList();
   1118     assertEquals(bindings.toString(), 3, bindings.size());
   1119     Binding<String> a = bindings.get(0);
   1120     Binding<String> b = bindings.get(1);
   1121     Binding<String> c = bindings.get(2);
   1122     assertEquals("A", ((InstanceBinding<String>) a).getInstance());
   1123     assertEquals("b", ((InstanceBinding<String>) b).getInstance());
   1124     assertEquals("C", ((InstanceBinding<String>) c).getInstance());
   1125 
   1126     // Make sure the correct elements belong to their own sets.
   1127     assertFalse(collector.mapbinding.containsElement(a));
   1128     assertTrue(collector.mapbinding.containsElement(b));
   1129     assertFalse(collector.mapbinding.containsElement(c));
   1130 
   1131     assertTrue(collector.setbinding.containsElement(a));
   1132     assertFalse(collector.setbinding.containsElement(b));
   1133     assertFalse(collector.setbinding.containsElement(c));
   1134 
   1135     assertFalse(collector.optionalbinding.containsElement(a));
   1136     assertFalse(collector.optionalbinding.containsElement(b));
   1137     assertTrue(collector.optionalbinding.containsElement(c));
   1138   }
   1139 
   1140   public void testMultibinderCanInjectCollectionOfProviders() {
   1141     Module module = new AbstractModule() {
   1142       @Override protected void configure() {
   1143         final Multibinder<String> multibinder = Multibinder.newSetBinder(binder(), String.class);
   1144         multibinder.addBinding().toProvider(Providers.of("A"));
   1145         multibinder.addBinding().toProvider(Providers.of("B"));
   1146         multibinder.addBinding().toInstance("C");
   1147       }
   1148     };
   1149     Collection<String> expectedValues = ImmutableList.of("A", "B", "C");
   1150 
   1151     Injector injector = Guice.createInjector(module);
   1152 
   1153     Collection<Provider<String>> providers =
   1154         injector.getInstance(Key.get(collectionOfProvidersOfStrings));
   1155     assertEquals(expectedValues, collectValues(providers));
   1156 
   1157     Collection<javax.inject.Provider<String>> javaxProviders =
   1158         injector.getInstance(Key.get(collectionOfJavaxProvidersOf(stringType)));
   1159     assertEquals(expectedValues, collectValues(javaxProviders));
   1160   }
   1161 
   1162   public void testMultibinderCanInjectCollectionOfProvidersWithAnnotation() {
   1163     final Annotation ann = Names.named("foo");
   1164     Module module = new AbstractModule() {
   1165       @Override protected void configure() {
   1166         final Multibinder<String> multibinder =
   1167             Multibinder.newSetBinder(binder(), String.class, ann);
   1168         multibinder.addBinding().toProvider(Providers.of("A"));
   1169         multibinder.addBinding().toProvider(Providers.of("B"));
   1170         multibinder.addBinding().toInstance("C");
   1171       }
   1172     };
   1173     Collection<String> expectedValues = ImmutableList.of("A", "B", "C");
   1174 
   1175     Injector injector = Guice.createInjector(module);
   1176 
   1177     Collection<Provider<String>> providers =
   1178         injector.getInstance(Key.get(collectionOfProvidersOfStrings, ann));
   1179     Collection<String> values = collectValues(providers);
   1180     assertEquals(expectedValues, values);
   1181 
   1182     Collection<javax.inject.Provider<String>> javaxProviders =
   1183         injector.getInstance(Key.get(collectionOfJavaxProvidersOf(stringType), ann));
   1184     assertEquals(expectedValues, collectValues(javaxProviders));
   1185   }
   1186 
   1187   public void testMultibindingProviderDependencies() {
   1188     final Annotation setAnn = Names.named("foo");
   1189     Injector injector = Guice.createInjector(new AbstractModule() {
   1190         @Override protected void configure() {
   1191           Multibinder<String> multibinder =
   1192               Multibinder.newSetBinder(binder(), String.class, setAnn);
   1193           multibinder.addBinding().toInstance("a");
   1194           multibinder.addBinding().toInstance("b");
   1195         }
   1196       });
   1197     HasDependencies providerBinding =
   1198       (HasDependencies) injector.getBinding(new Key<Collection<Provider<String>>>(setAnn) {});
   1199     HasDependencies setBinding =
   1200       (HasDependencies) injector.getBinding(new Key<Set<String>>(setAnn) {});
   1201     // sanity check the size
   1202     assertEquals(setBinding.getDependencies().toString(), 2, setBinding.getDependencies().size());
   1203     Set<Dependency<?>> expected = Sets.newHashSet();
   1204     for (Dependency<?> dep : setBinding.getDependencies()) {
   1205       Key key = dep.getKey();
   1206       Dependency<?> providerDependency =
   1207           Dependency.get(key.ofType(Types.providerOf(key.getTypeLiteral().getType())));
   1208       expected.add(providerDependency);
   1209     }
   1210     assertEquals(expected, providerBinding.getDependencies());
   1211   }
   1212 
   1213   private <T> Collection<T> collectValues(
   1214       Collection<? extends javax.inject.Provider<T>> providers) {
   1215     Collection<T> values = Lists.newArrayList();
   1216     for (javax.inject.Provider<T> provider : providers) {
   1217       values.add(provider.get());
   1218     }
   1219     return values;
   1220   }
   1221 }
   1222