1af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber/**
2af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * Copyright (C) 2014 Google Inc.
3af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
4af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * Licensed under the Apache License, Version 2.0 (the "License");
5af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * you may not use this file except in compliance with the License.
6af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * You may obtain a copy of the License at
7af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
8af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * http://www.apache.org/licenses/LICENSE-2.0
9af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
10af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * Unless required by applicable law or agreed to in writing, software
11af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * distributed under the License is distributed on an "AS IS" BASIS,
12af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * See the License for the specific language governing permissions and
14af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * limitations under the License.
15af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber */
16af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
17af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberpackage com.google.inject.multibindings;
18af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
19af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport static com.google.common.base.Preconditions.checkNotNull;
201d3f8cd0a163c7439589d80e6377edbf2ca4b43dsamebimport static com.google.common.base.Preconditions.checkState;
21af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport static com.google.inject.multibindings.Multibinder.checkConfiguration;
22af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport static com.google.inject.util.Types.newParameterizedType;
23c66f08e3d6798e88f35be51679854568f337e7ebSam Berlinimport static java.lang.annotation.RetentionPolicy.RUNTIME;
24af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
25af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.common.base.Optional;
261d3f8cd0a163c7439589d80e6377edbf2ca4b43dsamebimport com.google.common.base.Throwables;
27af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.common.collect.ImmutableSet;
28af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.Binder;
29af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.Binding;
30af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.Inject;
31af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.Injector;
32af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.Key;
33af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.Module;
34af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.Provider;
35af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.TypeLiteral;
36af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.binder.LinkedBindingBuilder;
37af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.spi.BindingTargetVisitor;
38af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.spi.Dependency;
39c66f08e3d6798e88f35be51679854568f337e7ebSam Berlinimport com.google.inject.spi.Element;
40af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.spi.ProviderInstanceBinding;
41af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.spi.ProviderLookup;
42af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.spi.ProviderWithDependencies;
43af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.spi.ProviderWithExtensionVisitor;
44af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.spi.Toolable;
45af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport com.google.inject.util.Types;
46af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
47c66f08e3d6798e88f35be51679854568f337e7ebSam Berlinimport java.io.Serializable;
48c66f08e3d6798e88f35be51679854568f337e7ebSam Berlinimport java.lang.annotation.Annotation;
49c66f08e3d6798e88f35be51679854568f337e7ebSam Berlinimport java.lang.annotation.Retention;
501d3f8cd0a163c7439589d80e6377edbf2ca4b43dsamebimport java.lang.reflect.InvocationTargetException;
511d3f8cd0a163c7439589d80e6377edbf2ca4b43dsamebimport java.lang.reflect.Method;
52c66f08e3d6798e88f35be51679854568f337e7ebSam Berlinimport java.lang.reflect.Type;
53af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberimport java.util.Set;
54af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
55c66f08e3d6798e88f35be51679854568f337e7ebSam Berlinimport javax.inject.Qualifier;
56c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
57af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
58af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber/**
59af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * An API to bind optional values, optionally with a default value.
60af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * OptionalBinder fulfills two roles: <ol>
61af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <li>It allows a framework to define an injection point that may or
62af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *     may not be bound by users.
63af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <li>It allows a framework to supply a default value that can be changed
64af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *     by users.
65af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * </ol>
66af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
67af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <p>When an OptionalBinder is added, it will always supply the bindings:
68af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * {@code Optional<T>} and {@code Optional<Provider<T>>}.  If
69af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * {@link #setBinding} or {@link #setDefault} are called, it will also
70af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * bind {@code T}.
71af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
72af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <p>{@code setDefault} is intended for use by frameworks that need a default
73af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * value.  User code can call {@code setBinding} to override the default.
74af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <b>Warning: Even if setBinding is called, the default binding
75af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * will still exist in the object graph.  If it is a singleton, it will be
76af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * instantiated in {@code Stage.PRODUCTION}.</b>
77af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
78af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <p>If setDefault or setBinding are linked to Providers, the Provider may return
79af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * {@code null}.  If it does, the Optional bindings will be absent.  Binding
80af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * setBinding to a Provider that returns null will not cause OptionalBinder
81af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * to fall back to the setDefault binding.
82af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
83842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * <p>If neither setDefault nor setBinding are called, it will try to link to a
84842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * user-supplied binding of the same type.  If no binding exists, the optionals
85842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * will be absent.  Otherwise, if a user-supplied binding of that type exists,
86842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * or if setBinding or setDefault are called, the optionals will return present
87842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * if they are bound to a non-null value.
88af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
89af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <p>Values are resolved at injection time. If a value is bound to a
90af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * provider, that provider's get method will be called each time the optional
91af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * is injected (unless the binding is also scoped, or an optional of provider is
92af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * injected).
93af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
94af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <p>Annotations are used to create different optionals of the same key/value
95af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * type. Each distinct annotation gets its own independent binding.
96af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
97af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <pre><code>
98af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * public class FrameworkModule extends AbstractModule {
99af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   protected void configure() {
100af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *     OptionalBinder.newOptionalBinder(binder(), Renamer.class);
101af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   }
102af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * }</code></pre>
103af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
104af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <p>With this module, an {@link Optional}{@code <Renamer>} can now be
105842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * injected.  With no other bindings, the optional will be absent.
106842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * Users can specify bindings in one of two ways:
107af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
108842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * <p>Option 1:
109842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * <pre><code>
110842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * public class UserRenamerModule extends AbstractModule {
111842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *   protected void configure() {
112842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *     bind(Renamer.class).to(ReplacingRenamer.class);
113842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *   }
114842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * }</code></pre>
115842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *
116842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * <p>or Option 2:
117af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <pre><code>
118af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * public class UserRenamerModule extends AbstractModule {
119af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   protected void configure() {
120af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *     OptionalBinder.newOptionalBinder(binder(), Renamer.class)
121af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *         .setBinding().to(ReplacingRenamer.class);
122af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   }
123af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * }</code></pre>
124842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * With both options, the {@code Optional<Renamer>} will be present and supply the
125842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * ReplacingRenamer.
126af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
127af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <p>Default values can be supplied using:
128af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <pre><code>
129af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * public class FrameworkModule extends AbstractModule {
130af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   protected void configure() {
131af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
13232780fa2a30bb10f7c85a0a43845308af7bcefddchristophf *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
133af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   }
134af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * }</code></pre>
135af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * With the above module, code can inject an {@code @LookupUrl String} and it
136af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * will supply the DEFAULT_LOOKUP_URL.  A user can change this value by binding
137af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * <pre><code>
138af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * public class UserLookupModule extends AbstractModule {
139af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   protected void configure() {
140af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
14132780fa2a30bb10f7c85a0a43845308af7bcefddchristophf *         .setBinding().toInstance(CUSTOM_LOOKUP_URL);
142af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *   }
143af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * }</code></pre>
144af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * ... which will override the default value.
145842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *
146842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * <p>If one module uses setDefault the only way to override the default is to use setBinding.
147842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * It is an error for a user to specify the binding without using OptionalBinder if
148842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * setDefault or setBinding are called.  For example,
149842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * <pre><code>
150842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * public class FrameworkModule extends AbstractModule {
151842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *   protected void configure() {
152842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
15332780fa2a30bb10f7c85a0a43845308af7bcefddchristophf *         .setDefault().toInstance(DEFAULT_LOOKUP_URL);
154842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *   }
155842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * }
156842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * public class UserLookupModule extends AbstractModule {
157842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *   protected void configure() {
15832780fa2a30bb10f7c85a0a43845308af7bcefddchristophf *     bind(Key.get(String.class, LookupUrl.class)).toInstance(CUSTOM_LOOKUP_URL);
159842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin *   }
160842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * }</code></pre>
161842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * ... would generate an error, because both the framework and the user are trying to bind
162842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin * {@code @LookupUrl String}.
163af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber *
164af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber * @author sameb@google.com (Sam Berlin)
165bac730fa1b717351736182034aff62827a383090Ben McCann * @since 4.0
166af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber */
167af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruberpublic abstract class OptionalBinder<T> {
1681d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
1691d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  /* Reflectively capture java 8's Optional types so we can bind them if we're running in java8. */
1701d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  private static final Class<?> JAVA_OPTIONAL_CLASS;
1711d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  private static final Method JAVA_EMPTY_METHOD;
1721d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  private static final Method JAVA_OF_NULLABLE_METHOD;
1731d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  static {
1741d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    Class<?> optional = null;
1751d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    Method empty = null;
1761d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    Method ofNullable = null;
1771d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    boolean useJavaOptional = false;
1781d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    try {
1791d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      optional = Class.forName("java.util.Optional");
1801d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      empty = optional.getDeclaredMethod("empty");
1811d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      ofNullable = optional.getDeclaredMethod("ofNullable", Object.class);
1821d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      useJavaOptional = true;
1831d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    } catch (ClassNotFoundException ignored) {
1841d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    } catch (NoSuchMethodException ignored) {
1851d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    } catch (SecurityException ignored) {
1861d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
1871d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    JAVA_OPTIONAL_CLASS = useJavaOptional ? optional : null;
1881d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    JAVA_EMPTY_METHOD = useJavaOptional ? empty : null;
1891d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    JAVA_OF_NULLABLE_METHOD = useJavaOptional ? ofNullable : null;
1901d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  }
1911d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
192af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  private OptionalBinder() {}
193af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
194af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Class<T> type) {
1950b33461e35fa3a769ce23a9812a80acdc281f62csameb    return newRealOptionalBinder(binder, Key.get(type));
196af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  }
197af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
198af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, TypeLiteral<T> type) {
1990b33461e35fa3a769ce23a9812a80acdc281f62csameb    return newRealOptionalBinder(binder, Key.get(type));
200af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  }
201af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
202af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Key<T> type) {
2030b33461e35fa3a769ce23a9812a80acdc281f62csameb    return newRealOptionalBinder(binder, type);
2040b33461e35fa3a769ce23a9812a80acdc281f62csameb  }
2050b33461e35fa3a769ce23a9812a80acdc281f62csameb
2060b33461e35fa3a769ce23a9812a80acdc281f62csameb  static <T> RealOptionalBinder<T> newRealOptionalBinder(Binder binder, Key<T> type) {
207af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    binder = binder.skipSources(OptionalBinder.class, RealOptionalBinder.class);
208af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    RealOptionalBinder<T> optionalBinder = new RealOptionalBinder<T>(binder, type);
209af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    binder.install(optionalBinder);
210af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    return optionalBinder;
211af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  }
212af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
213af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  @SuppressWarnings("unchecked")
214af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  static <T> TypeLiteral<Optional<T>> optionalOf(
215af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      TypeLiteral<T> type) {
216af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    return (TypeLiteral<Optional<T>>) TypeLiteral.get(
217af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        Types.newParameterizedType(Optional.class,  type.getType()));
218af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  }
219af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
2201d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  static <T> TypeLiteral<?> javaOptionalOf(
2211d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      TypeLiteral<T> type) {
2221d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
2231d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS, type.getType()));
2241d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  }
2251d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
226af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  @SuppressWarnings("unchecked")
227af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  static <T> TypeLiteral<Optional<javax.inject.Provider<T>>> optionalOfJavaxProvider(
228af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      TypeLiteral<T> type) {
229af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    return (TypeLiteral<Optional<javax.inject.Provider<T>>>) TypeLiteral.get(
230af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        Types.newParameterizedType(Optional.class,
231af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber            newParameterizedType(javax.inject.Provider.class, type.getType())));
232af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  }
233af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
2341d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  static <T> TypeLiteral<?> javaOptionalOfJavaxProvider(
2351d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      TypeLiteral<T> type) {
2361d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
2371d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS,
2381d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        newParameterizedType(javax.inject.Provider.class, type.getType())));
2391d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  }
2401d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
241af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  @SuppressWarnings("unchecked")
242af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  static <T> TypeLiteral<Optional<Provider<T>>> optionalOfProvider(TypeLiteral<T> type) {
243af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    return (TypeLiteral<Optional<Provider<T>>>) TypeLiteral.get(Types.newParameterizedType(
244af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        Optional.class, newParameterizedType(Provider.class, type.getType())));
245af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  }
2461d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
2471d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  static <T> TypeLiteral<?> javaOptionalOfProvider(TypeLiteral<T> type) {
2481d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    checkState(JAVA_OPTIONAL_CLASS != null, "java.util.Optional not found");
2491d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    return TypeLiteral.get(Types.newParameterizedType(JAVA_OPTIONAL_CLASS,
2501d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        newParameterizedType(Provider.class, type.getType())));
2511d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb  }
2521d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
253c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  @SuppressWarnings("unchecked")
254c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  static <T> Key<Provider<T>> providerOf(Key<T> key) {
255c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    Type providerT = Types.providerOf(key.getTypeLiteral().getType());
256c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    return (Key<Provider<T>>) key.ofType(providerT);
257c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  }
258af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
259af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  /**
260af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * Returns a binding builder used to set the default value that will be injected.
261af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * The binding set by this method will be ignored if {@link #setBinding} is called.
262af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   *
263af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * <p>It is an error to call this method without also calling one of the {@code to}
264af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * methods on the returned binding builder.
265af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   */
266af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  public abstract LinkedBindingBuilder<T> setDefault();
267af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
268af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
269af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  /**
270af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * Returns a binding builder used to set the actual value that will be injected.
271af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * This overrides any binding set by {@link #setDefault}.
272af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   *
273af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * <p>It is an error to call this method without also calling one of the {@code to}
274af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * methods on the returned binding builder.
275af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   */
276af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  public abstract LinkedBindingBuilder<T> setBinding();
277af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
278af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  enum Source { DEFAULT, ACTUAL }
279c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
280c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  @Retention(RUNTIME)
281c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  @Qualifier
282c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  @interface Default {
283c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    String value();
284c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  }
285c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
286c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  @Retention(RUNTIME)
287c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  @Qualifier
288c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  @interface Actual {
289c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    String value();
290c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  }
291af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
292af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  /**
293af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * The actual OptionalBinder plays several roles.  It implements Module to hide that
294af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   * fact from the public API, and installs the various bindings that are exposed to the user.
295af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber   */
296af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  static final class RealOptionalBinder<T> extends OptionalBinder<T> implements Module {
297af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private final Key<T> typeKey;
298af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private final Key<Optional<T>> optionalKey;
299af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private final Key<Optional<javax.inject.Provider<T>>> optionalJavaxProviderKey;
300af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private final Key<Optional<Provider<T>>> optionalProviderKey;
301af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private final Provider<Optional<Provider<T>>> optionalProviderT;
302c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private final Key<T> defaultKey;
303c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private final Key<T> actualKey;
304af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
3051d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private final Key javaOptionalKey;
3061d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private final Key javaOptionalJavaxProviderKey;
3071d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private final Key javaOptionalProviderKey;
3081d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
309af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    /** the target injector's binder. non-null until initialization, null afterwards */
310af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private Binder binder;
311af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    /** the default binding, for the SPI. */
312c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private Binding<T> defaultBinding;
313af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    /** the actual binding, for the SPI */
314c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private Binding<T> actualBinding;
315c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
316c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    /** the dependencies -- initialized with defaults & overridden when tooled. */
317c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private Set<Dependency<?>> dependencies;
318c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    /** the dependencies -- initialized with defaults & overridden when tooled. */
319c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private Set<Dependency<?>> providerDependencies;
320af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
321af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private RealOptionalBinder(Binder binder, Key<T> typeKey) {
322af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      this.binder = binder;
323af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      this.typeKey = checkNotNull(typeKey);
324af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      TypeLiteral<T> literal = typeKey.getTypeLiteral();
325af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      this.optionalKey = typeKey.ofType(optionalOf(literal));
326af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      this.optionalJavaxProviderKey = typeKey.ofType(optionalOfJavaxProvider(literal));
327af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      this.optionalProviderKey = typeKey.ofType(optionalOfProvider(literal));
328af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      this.optionalProviderT = binder.getProvider(optionalProviderKey);
329c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      String name = RealElement.nameOf(typeKey);
330c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      this.defaultKey = Key.get(typeKey.getTypeLiteral(), new DefaultImpl(name));
331c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      this.actualKey = Key.get(typeKey.getTypeLiteral(), new ActualImpl(name));
332c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      // Until the injector initializes us, we don't know what our dependencies are,
333c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      // so initialize to the whole Injector (like Multibinder, and MapBinder indirectly).
334c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      this.dependencies = ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
335c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      this.providerDependencies =
336c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin          ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
3371d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
3381d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      if (JAVA_OPTIONAL_CLASS != null) {
3391d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        this.javaOptionalKey = typeKey.ofType(javaOptionalOf(literal));
3401d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        this.javaOptionalJavaxProviderKey = typeKey.ofType(javaOptionalOfJavaxProvider(literal));
3411d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        this.javaOptionalProviderKey = typeKey.ofType(javaOptionalOfProvider(literal));
3421d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      } else {
3431d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        this.javaOptionalKey = null;
3441d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        this.javaOptionalJavaxProviderKey = null;
3451d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        this.javaOptionalProviderKey = null;
3461d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
347af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
3481d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
349af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    /**
350af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber     * Adds a binding for T. Multiple calls to this are safe, and will be collapsed as duplicate
351af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber     * bindings.
352af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber     */
353af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private void addDirectTypeBinding(Binder binder) {
3549c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      binder.bind(typeKey).toProvider(new RealDirectTypeProvider());
355af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
356af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
3570b33461e35fa3a769ce23a9812a80acdc281f62csameb    Key<T> getKeyForDefaultBinding() {
358c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      checkConfiguration(!isInitialized(), "already initialized");
359af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      addDirectTypeBinding(binder);
3600b33461e35fa3a769ce23a9812a80acdc281f62csameb      return defaultKey;
361af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
362af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
3630b33461e35fa3a769ce23a9812a80acdc281f62csameb    @Override public LinkedBindingBuilder<T> setDefault() {
3640b33461e35fa3a769ce23a9812a80acdc281f62csameb      return binder.bind(getKeyForDefaultBinding());
3650b33461e35fa3a769ce23a9812a80acdc281f62csameb    }
3660b33461e35fa3a769ce23a9812a80acdc281f62csameb
3670b33461e35fa3a769ce23a9812a80acdc281f62csameb    Key<T> getKeyForActualBinding() {
368c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      checkConfiguration(!isInitialized(), "already initialized");
369af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      addDirectTypeBinding(binder);
3700b33461e35fa3a769ce23a9812a80acdc281f62csameb      return actualKey;
3710b33461e35fa3a769ce23a9812a80acdc281f62csameb    }
3720b33461e35fa3a769ce23a9812a80acdc281f62csameb
3730b33461e35fa3a769ce23a9812a80acdc281f62csameb    @Override public LinkedBindingBuilder<T> setBinding() {
3740b33461e35fa3a769ce23a9812a80acdc281f62csameb      return binder.bind(getKeyForActualBinding());
375af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
376af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
377842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin    @Override public void configure(Binder binder) {
378af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      checkConfiguration(!isInitialized(), "OptionalBinder was already initialized");
379af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
3809c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      binder.bind(optionalProviderKey).toProvider(new RealOptionalProviderProvider());
381af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
382af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      // Optional is immutable, so it's safe to expose Optional<Provider<T>> as
383af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      // Optional<javax.inject.Provider<T>> (since Guice provider implements javax Provider).
384af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      @SuppressWarnings({"unchecked", "cast"})
385af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      Key massagedOptionalProviderKey = (Key) optionalProviderKey;
386af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      binder.bind(optionalJavaxProviderKey).to(massagedOptionalProviderKey);
387af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
388af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      binder.bind(optionalKey).toProvider(new RealOptionalKeyProvider());
3891d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
3901d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      // Bind the java-8 types if we know them.
3911d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      bindJava8Optional(binder);
3921d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
3931d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
3941d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    @SuppressWarnings("unchecked")
3951d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private void bindJava8Optional(Binder binder) {
3961d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      if (JAVA_OPTIONAL_CLASS != null) {
3971d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        binder.bind(javaOptionalKey).toProvider(new JavaOptionalProvider());
3981d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        binder.bind(javaOptionalProviderKey).toProvider(new JavaOptionalProviderProvider());
3991d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        // for the javax version we reuse the guice version since they're type-compatible.
4001d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        binder.bind(javaOptionalJavaxProviderKey).to(javaOptionalProviderKey);
4011d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4021d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
4031d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4041d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    @SuppressWarnings("rawtypes")
4051d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    final class JavaOptionalProvider extends RealOptionalBinderProviderWithDependencies
4061d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        implements ProviderWithExtensionVisitor, OptionalBinderBinding {
4071d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      private JavaOptionalProvider() {
4081d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        super(typeKey);
4091d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4101d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4111d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Object get() {
4121d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        Optional<Provider<T>> optional = optionalProviderT.get();
4131d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        try {
4141d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          if (optional.isPresent()) {
4151d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            return JAVA_OF_NULLABLE_METHOD.invoke(JAVA_OPTIONAL_CLASS, optional.get().get());
4161d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          } else {
4171d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            return JAVA_EMPTY_METHOD.invoke(JAVA_OPTIONAL_CLASS);
4181d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          }
4191d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        } catch (IllegalAccessException e) {
4201d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          throw new SecurityException(e);
4211d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        } catch (IllegalArgumentException e) {
4221d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          throw new IllegalStateException(e);
4231d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        } catch (InvocationTargetException e) {
4241d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          throw Throwables.propagate(e.getCause());
4251d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        }
4261d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4271d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4281d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Set<Dependency<?>> getDependencies() {
4291d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return dependencies;
4301d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4311d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4321d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @SuppressWarnings("unchecked")
4331d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Object acceptExtensionVisitor(BindingTargetVisitor visitor,
4341d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          ProviderInstanceBinding binding) {
4351d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        if (visitor instanceof MultibindingsTargetVisitor) {
4361d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          return ((MultibindingsTargetVisitor) visitor).visit(this);
4371d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        } else {
4381d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          return visitor.visit(binding);
4391d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        }
4401d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4411d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4421d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public boolean containsElement(Element element) {
4431d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return RealOptionalBinder.this.containsElement(element);
4441d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4451d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4461d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Binding getActualBinding() {
4471d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return RealOptionalBinder.this.getActualBinding();
4481d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4491d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4501d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Binding getDefaultBinding() {
4511d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return RealOptionalBinder.this.getDefaultBinding();
4521d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4531d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4541d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Key getKey() {
4551d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return javaOptionalKey;
4561d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4571d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
4581d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4591d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    @SuppressWarnings("rawtypes")
4601d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    final class JavaOptionalProviderProvider extends RealOptionalBinderProviderWithDependencies {
4611d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      private JavaOptionalProviderProvider() {
4621d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        super(typeKey);
4631d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4641d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4651d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Object get() {
4661d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        Optional<Provider<T>> optional = optionalProviderT.get();
4671d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        try {
4681d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          if (optional.isPresent()) {
4691d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            return JAVA_OF_NULLABLE_METHOD.invoke(JAVA_OPTIONAL_CLASS, optional.get());
4701d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          } else {
4711d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            return JAVA_EMPTY_METHOD.invoke(JAVA_OPTIONAL_CLASS);
4721d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          }
4731d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        } catch (IllegalAccessException e) {
4741d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          throw new SecurityException(e);
4751d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        } catch (IllegalArgumentException e) {
4761d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          throw new IllegalStateException(e);
4771d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        } catch (InvocationTargetException e) {
4781d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          throw Throwables.propagate(e.getCause());
4791d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        }
4801d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
4811d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
4821d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      @Override public Set<Dependency<?>> getDependencies() {
4831d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return providerDependencies;
4841d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
485af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
486af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
4879c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin    final class RealDirectTypeProvider extends RealOptionalBinderProviderWithDependencies<T> {
4889c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      private RealDirectTypeProvider() {
4899c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        super(typeKey);
4909c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      }
4919c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
4929c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      @Override public T get() {
4939c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        Optional<Provider<T>> optional = optionalProviderT.get();
4949c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        if (optional.isPresent()) {
4959c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          return optional.get().get();
4969c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        }
4979c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        // Let Guice handle blowing up if the injection point doesn't have @Nullable
4989c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        // (If it does have @Nullable, that's fine.  This would only happen if
4999c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        //  setBinding/setDefault themselves were bound to 'null').
5009c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        return null;
5019c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      }
5029c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5039c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      @Override public Set<Dependency<?>> getDependencies() {
5049c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        return dependencies;
5059c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      }
5069c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin    }
5079c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5089c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin    final class RealOptionalProviderProvider
5099c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        extends RealOptionalBinderProviderWithDependencies<Optional<Provider<T>>> {
5109c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      private Optional<Provider<T>> optional;
5119c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5129c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      private RealOptionalProviderProvider() {
5139c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        super(typeKey);
5149c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      }
5159c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5169c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      @Toolable @Inject void initialize(Injector injector) {
5179c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        RealOptionalBinder.this.binder = null;
5189c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        actualBinding = injector.getExistingBinding(actualKey);
5199c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        defaultBinding = injector.getExistingBinding(defaultKey);
5209c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        Binding<T> userBinding = injector.getExistingBinding(typeKey);
5219c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        Binding<T> binding = null;
5229c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        if (actualBinding != null) {
5239c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          // TODO(sameb): Consider exposing an option that will allow
5249c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          // ACTUAL to fallback to DEFAULT if ACTUAL's provider returns null.
5259c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          // Right now, an ACTUAL binding can convert from present -> absent
5269c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          // if it's bound to a provider that returns null.
5279c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          binding = actualBinding;
5289c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        } else if (defaultBinding != null) {
5299c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          binding = defaultBinding;
5309c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        } else if (userBinding != null) {
5319c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          // If neither the actual or default is set, then we fallback
5329c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          // to the value bound to the type itself and consider that the
5339c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          // "actual binding" for the SPI.
5349c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          binding = userBinding;
5359c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          actualBinding = userBinding;
5369c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        }
5379c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5389c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        if (binding != null) {
5399c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          optional = Optional.of(binding.getProvider());
5409c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          RealOptionalBinder.this.dependencies =
5419c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin              ImmutableSet.<Dependency<?>>of(Dependency.get(binding.getKey()));
5429c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          RealOptionalBinder.this.providerDependencies =
5439c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin              ImmutableSet.<Dependency<?>>of(Dependency.get(providerOf(binding.getKey())));
5449c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        } else {
5459c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          optional = Optional.absent();
5469c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          RealOptionalBinder.this.dependencies = ImmutableSet.of();
5479c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin          RealOptionalBinder.this.providerDependencies = ImmutableSet.of();
5489c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        }
5499c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      }
5509c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5519c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      @Override public Optional<Provider<T>> get() {
5529c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        return optional;
5539c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      }
5549c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5559c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      @Override public Set<Dependency<?>> getDependencies() {
5569c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin        return providerDependencies;
5579c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      }
5589c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin    }
5599c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin
5609c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin    final class RealOptionalKeyProvider
561af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        extends RealOptionalBinderProviderWithDependencies<Optional<T>>
562af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        implements ProviderWithExtensionVisitor<Optional<T>>,
563af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber            OptionalBinderBinding<Optional<T>>,
564af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber            Provider<Optional<T>> {
5659c2457597fbfe89783f4a9065bab40ad149521a1Sam Berlin      private RealOptionalKeyProvider() {
566c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin        super(typeKey);
567af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
568af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
569842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public Optional<T> get() {
570af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        Optional<Provider<T>> optional = optionalProviderT.get();
571af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        if (optional.isPresent()) {
572af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber          return Optional.fromNullable(optional.get().get());
573af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        } else {
574af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber          return Optional.absent();
575af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        }
576af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
577af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
578842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public Set<Dependency<?>> getDependencies() {
579af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        return dependencies;
580af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
581af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
582af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      @SuppressWarnings("unchecked")
583842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override
584af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      public <B, R> R acceptExtensionVisitor(BindingTargetVisitor<B, R> visitor,
585af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber          ProviderInstanceBinding<? extends B> binding) {
586af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        if (visitor instanceof MultibindingsTargetVisitor) {
587af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber          return ((MultibindingsTargetVisitor<Optional<T>, R>) visitor).visit(this);
588af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        } else {
589af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber          return visitor.visit(binding);
590af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        }
591af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
592af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
593842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public Key<Optional<T>> getKey() {
594af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        return optionalKey;
595af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
5961d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
597842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public Binding<?> getActualBinding() {
5981d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return RealOptionalBinder.this.getActualBinding();
599af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
6001d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
601842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public Binding<?> getDefaultBinding() {
6021d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return RealOptionalBinder.this.getDefaultBinding();
603af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
604af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
605842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public boolean containsElement(Element element) {
6061d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return RealOptionalBinder.this.containsElement(element);
6071d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
6081d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
6091d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
6101d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private Binding<?> getActualBinding() {
6111d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      if (isInitialized()) {
6121d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return actualBinding;
6131d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      } else {
6141d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        throw new UnsupportedOperationException(
6151d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            "getActualBinding() not supported from Elements.getElements, requires an Injector.");
6161d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
6171d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
6181d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
6191d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private Binding<?> getDefaultBinding() {
6201d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      if (isInitialized()) {
6211d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return defaultBinding;
6221d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      } else {
6231d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        throw new UnsupportedOperationException(
6241d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            "getDefaultBinding() not supported from Elements.getElements, requires an Injector.");
6251d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
6261d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
6271d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
6281d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private boolean containsElement(Element element) {
6291d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      Key<?> elementKey;
6301d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      if (element instanceof Binding) {
6311d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        elementKey = ((Binding<?>) element).getKey();
6321d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      } else if (element instanceof ProviderLookup) {
6331d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        elementKey = ((ProviderLookup<?>) element).getKey();
6341d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      } else {
6351d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return false; // cannot match;
6361d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      }
6371d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb
6381d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      return elementKey.equals(optionalKey)
6391d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          || elementKey.equals(optionalProviderKey)
6401d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          || elementKey.equals(optionalJavaxProviderKey)
6411d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          || elementKey.equals(defaultKey)
6421d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          || elementKey.equals(actualKey)
6431d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          || matchesJ8Keys(elementKey)
6441d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb          || matchesTypeKey(element, elementKey);
6451d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    }
646c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
6471d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb    private boolean matchesJ8Keys(Key<?> elementKey) {
6481d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      if (JAVA_OPTIONAL_CLASS != null) {
6491d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb        return elementKey.equals(javaOptionalKey)
6501d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            || elementKey.equals(javaOptionalProviderKey)
6511d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb            || elementKey.equals(javaOptionalJavaxProviderKey);
652af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
6531d3f8cd0a163c7439589d80e6377edbf2ca4b43dsameb      return false;
654af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
655af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
656af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    /** Returns true if the key & element indicate they were bound by this OptionalBinder. */
657c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private boolean matchesTypeKey(Element element, Key<?> elementKey) {
658af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      // Just doing .equals(typeKey) isn't enough, because the user can bind that themselves.
659af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      return elementKey.equals(typeKey)
660af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber          && element instanceof ProviderInstanceBinding
661af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber          && (((ProviderInstanceBinding) element)
662af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber              .getUserSuppliedProvider() instanceof RealOptionalBinderProviderWithDependencies);
663af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
664af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
665af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private boolean isInitialized() {
666af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      return binder == null;
667af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
668af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
669af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    @Override public boolean equals(Object o) {
670af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      return o instanceof RealOptionalBinder
671c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin          && ((RealOptionalBinder<?>) o).typeKey.equals(typeKey);
672af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
673af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
674af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    @Override public int hashCode() {
675c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      return typeKey.hashCode();
676af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
677af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
678af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    /**
679af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber     * A base class for ProviderWithDependencies that need equality based on a specific object.
680af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber     */
681af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    private abstract static class RealOptionalBinderProviderWithDependencies<T> implements
682af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        ProviderWithDependencies<T> {
683af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      private final Object equality;
684af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
685af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      public RealOptionalBinderProviderWithDependencies(Object equality) {
686af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        this.equality = equality;
687af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
688af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
689842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public boolean equals(Object obj) {
690af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        return this.getClass() == obj.getClass()
691af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber            && equality.equals(((RealOptionalBinderProviderWithDependencies<?>) obj).equality);
692af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
693af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber
694842f351c4b2b3b0a90d9f3bcf164d8fd19aede6cSam Berlin      @Override public int hashCode() {
695af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber        return equality.hashCode();
696af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber      }
697af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber    }
698af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber  }
699c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
700c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  static class DefaultImpl extends BaseAnnotation implements Default {
701c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    public DefaultImpl(String value) {
702c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      super(Default.class, value);
703c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
704c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  }
705c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
706c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  static class ActualImpl extends BaseAnnotation implements Actual {
707c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    public ActualImpl(String value) {
708c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      super(Actual.class, value);
709c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
710c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  }
711c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
712c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  abstract static class BaseAnnotation implements Serializable, Annotation {
713c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
714c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private final String value;
715c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private final Class<? extends Annotation> clazz;
716c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
717c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    BaseAnnotation(Class<? extends Annotation> clazz, String value) {
718c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      this.clazz = checkNotNull(clazz, "clazz");
719c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      this.value = checkNotNull(value, "value");
720c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
721c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
722c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    public String value() {
723c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      return this.value;
724c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
725c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
726c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    @Override public int hashCode() {
727c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      // This is specified in java.lang.Annotation.
728c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      return (127 * "value".hashCode()) ^ value.hashCode();
729c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
730c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
731c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    @Override public boolean equals(Object o) {
73208125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin      // We check against each annotation type instead of BaseAnnotation
73308125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin      // so that we can compare against generated annotation implementations.
73408125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin      if (o instanceof Actual && clazz == Actual.class) {
73508125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin        Actual other = (Actual) o;
73608125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin        return value.equals(other.value());
73708125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin      } else if (o instanceof Default && clazz == Default.class) {
73808125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin        Default other = (Default) o;
73908125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin        return value.equals(other.value());
740c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      }
74108125e9287e577e167ca1186eeff9e14c51250c4Sam Berlin      return false;
742c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
743c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
744c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    @Override public String toString() {
745c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      return "@" + clazz.getName() + (value.isEmpty() ? "" : "(value=" + value + ")");
746c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
747c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
748c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    @Override public Class<? extends Annotation> annotationType() {
749c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin      return clazz;
750c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    }
751c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin
752c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin    private static final long serialVersionUID = 0;
753c66f08e3d6798e88f35be51679854568f337e7ebSam Berlin  }
754af24f632f90fc91daeb30172b874405c131592c8Christian Edward Gruber}
755