// Path: sangria-core/src/main/java/com/tavianator/sangria/core/DelayedError.java
// public class DelayedError {
//     private Throwable error;
//     private boolean reported = false;
// 
//     /**
//      * Create a {@link DelayedError}.
//      *
//      * @param binder  The binder to attach the error to.
//      * @param message The format string for the message.
//      * @param args    Arguments that will be passed to the format string.
//      * @return A {@link DelayedError} token that can be canceled later.
//      * @see Binder#addError(String, Object...)
//      */
//     public static DelayedError create(Binder binder, String message, Object... args) {
//         return create(binder, new Message(PrettyTypes.format(message, args)));
//     }
// 
//     /**
//      * Create a {@link DelayedError}.
//      *
//      * @param binder The binder to attach the error to.
//      * @param t      The {@link Throwable} that caused this potential error.
//      * @return A {@link DelayedError} token that can be canceled later.
//      * @see Binder#addError(Throwable)
//      */
//     public static DelayedError create(Binder binder, Throwable t) {
//         DelayedError error = new DelayedError(t);
//         binder.skipSources(DelayedError.class)
//                 .requestInjection(error);
//         return error;
//     }
// 
//     /**
//      * Create a {@link DelayedError}.
//      *
//      * @param binder  The binder to attach the error to.
//      * @param message The error message.
//      * @return A {@link DelayedError} token that can be canceled later.
//      * @see Binder#addError(Message)
//      */
//     public static DelayedError create(Binder binder, Message message) {
//         // Using CreationException allows Guice to extract the Message and format it nicely
//         return create(binder, new CreationException(ImmutableList.of(message)));
//     }
// 
//     private DelayedError(Throwable error) {
//         this.error = error;
//     }
// 
//     /**
//      * Cancel this error.
//      */
//     public void cancel() {
//         checkState(!reported, "This error has already been reported");
//         error = null;
//     }
// 
//     @Inject
//     void reportErrors(Injector injector) throws Throwable {
//         reported = true;
//         if (error != null) {
//             throw error;
//         }
//     }
// }
// 
// Path: sangria-core/src/main/java/com/tavianator/sangria/core/UniqueAnnotations.java
// public class UniqueAnnotations {
//     private static final AtomicLong SEQUENCE = new AtomicLong();
// 
//     private UniqueAnnotations() {
//         // Not for instantiating
//     }
// 
//     @Retention(RetentionPolicy.RUNTIME)
//     @Qualifier
//     @VisibleForTesting
//     @interface UniqueAnnotation {
//         long value();
//     }
// 
//     /**
//      * Actual implementation of {@link UniqueAnnotation}.
//      */
//     @SuppressWarnings("ClassExplicitlyAnnotation")
//     private static class UniqueAnnotationImpl implements UniqueAnnotation {
//         private final long value;
// 
//         UniqueAnnotationImpl(long value) {
//             this.value = value;
//         }
// 
//         @Override
//         public long value() {
//             return value;
//         }
// 
//         public Class<? extends Annotation> annotationType() {
//             return UniqueAnnotation.class;
//         }
// 
//         @Override
//         public String toString() {
//             return "@" + UniqueAnnotation.class.getName() + "(value=" + value + ")";
//         }
// 
//         @Override
//         public boolean equals(Object obj) {
//             if (obj == this) {
//                 return true;
//             } else if (!(obj instanceof UniqueAnnotation)) {
//                 return false;
//             }
// 
//             UniqueAnnotation other = (UniqueAnnotation)obj;
//             return value == other.value();
//         }
// 
//         @Override
//         public int hashCode() {
//             return (127*"value".hashCode()) ^ Long.valueOf(value).hashCode();
//         }
//     }
// 
//     /**
//      * @return An {@link Annotation} that will be unequal to every other annotation.
//      */
//     public static Annotation create() {
//         return create(SEQUENCE.getAndIncrement());
//     }
// 
//     @VisibleForTesting
//     static Annotation create(long value) {
//         return new UniqueAnnotationImpl(value);
//     }
// }


import java.lang.annotation.Annotation;
import java.util.*;
import javax.inject.Inject;
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.ConfigurationException;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matcher;
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.DependencyAndSource;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderWithExtensionVisitor;
import com.google.inject.spi.ProvisionListener;
import com.tavianator.sangria.core.DelayedError;
import com.tavianator.sangria.core.UniqueAnnotations;

        @Override
        public ContextSensitiveBindingBuilder<T> annotatedWith(Annotation annotation) {
            error.cancel();
            return new BindingBuilder<>(Key.get(bindingKey.getTypeLiteral(), annotation));
        }

        @Override
        public void toContextSensitiveProvider(Class<? extends ContextSensitiveProvider<? extends T>> type) {
            toContextSensitiveProvider(Key.get(type));
        }

        @Override
        public void toContextSensitiveProvider(TypeLiteral<? extends ContextSensitiveProvider<? extends T>> type) {
            toContextSensitiveProvider(Key.get(type));
        }

        @Override
        public void toContextSensitiveProvider(Key<? extends ContextSensitiveProvider<? extends T>> key) {
            error.cancel();

            Provider<? extends ContextSensitiveProvider<? extends T>> provider = binder.getProvider(makeUniqueLinkedKey(key));
            binder.bind(bindingKey).toProvider(new ProviderKeyAdapter<>(provider, key));
            binder.bindListener(new BindingMatcher(bindingKey), new Trigger(bindingKey));
        }

        /**
         * For Binder#requireExplicitBindings() support.
         */
        private <U> Key<U> makeUniqueLinkedKey(Key<U> key) {
// Path: sangria-core/src/main/java/com/tavianator/sangria/core/DelayedError.java
// public class DelayedError {
//     private Throwable error;
//     private boolean reported = false;
// 
//     /**
//      * Create a {@link DelayedError}.
//      *
//      * @param binder  The binder to attach the error to.
//      * @param message The format string for the message.
//      * @param args    Arguments that will be passed to the format string.
//      * @return A {@link DelayedError} token that can be canceled later.
//      * @see Binder#addError(String, Object...)
//      */
//     public static DelayedError create(Binder binder, String message, Object... args) {
//         return create(binder, new Message(PrettyTypes.format(message, args)));
//     }
// 
//     /**
//      * Create a {@link DelayedError}.
//      *
//      * @param binder The binder to attach the error to.
//      * @param t      The {@link Throwable} that caused this potential error.
//      * @return A {@link DelayedError} token that can be canceled later.
//      * @see Binder#addError(Throwable)
//      */
//     public static DelayedError create(Binder binder, Throwable t) {
//         DelayedError error = new DelayedError(t);
//         binder.skipSources(DelayedError.class)
//                 .requestInjection(error);
//         return error;
//     }
// 
//     /**
//      * Create a {@link DelayedError}.
//      *
//      * @param binder  The binder to attach the error to.
//      * @param message The error message.
//      * @return A {@link DelayedError} token that can be canceled later.
//      * @see Binder#addError(Message)
//      */
//     public static DelayedError create(Binder binder, Message message) {
//         // Using CreationException allows Guice to extract the Message and format it nicely
//         return create(binder, new CreationException(ImmutableList.of(message)));
//     }
// 
//     private DelayedError(Throwable error) {
//         this.error = error;
//     }
// 
//     /**
//      * Cancel this error.
//      */
//     public void cancel() {
//         checkState(!reported, "This error has already been reported");
//         error = null;
//     }
// 
//     @Inject
//     void reportErrors(Injector injector) throws Throwable {
//         reported = true;
//         if (error != null) {
//             throw error;
//         }
//     }
// }
// 
// Path: sangria-core/src/main/java/com/tavianator/sangria/core/UniqueAnnotations.java
// public class UniqueAnnotations {
//     private static final AtomicLong SEQUENCE = new AtomicLong();
// 
//     private UniqueAnnotations() {
//         // Not for instantiating
//     }
// 
//     @Retention(RetentionPolicy.RUNTIME)
//     @Qualifier
//     @VisibleForTesting
//     @interface UniqueAnnotation {
//         long value();
//     }
// 
//     /**
//      * Actual implementation of {@link UniqueAnnotation}.
//      */
//     @SuppressWarnings("ClassExplicitlyAnnotation")
//     private static class UniqueAnnotationImpl implements UniqueAnnotation {
//         private final long value;
// 
//         UniqueAnnotationImpl(long value) {
//             this.value = value;
//         }
// 
//         @Override
//         public long value() {
//             return value;
//         }
// 
//         public Class<? extends Annotation> annotationType() {
//             return UniqueAnnotation.class;
//         }
// 
//         @Override
//         public String toString() {
//             return "@" + UniqueAnnotation.class.getName() + "(value=" + value + ")";
//         }
// 
//         @Override
//         public boolean equals(Object obj) {
//             if (obj == this) {
//                 return true;
//             } else if (!(obj instanceof UniqueAnnotation)) {
//                 return false;
//             }
// 
//             UniqueAnnotation other = (UniqueAnnotation)obj;
//             return value == other.value();
//         }
// 
//         @Override
//         public int hashCode() {
//             return (127*"value".hashCode()) ^ Long.valueOf(value).hashCode();
//         }
//     }
// 
//     /**
//      * @return An {@link Annotation} that will be unequal to every other annotation.
//      */
//     public static Annotation create() {
//         return create(SEQUENCE.getAndIncrement());
//     }
// 
//     @VisibleForTesting
//     static Annotation create(long value) {
//         return new UniqueAnnotationImpl(value);
//     }
// }


// Path: sangria-contextual/src/main/java/com/tavianator/sangria/contextual/ContextSensitiveBinder.java
import java.lang.annotation.Annotation;
import java.util.*;
import javax.inject.Inject;
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.ConfigurationException;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matcher;
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.DependencyAndSource;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderWithExtensionVisitor;
import com.google.inject.spi.ProvisionListener;
import com.tavianator.sangria.core.DelayedError;
import com.tavianator.sangria.core.UniqueAnnotations;


        @Override
        public ContextSensitiveBindingBuilder<T> annotatedWith(Annotation annotation) {
            error.cancel();
            return new BindingBuilder<>(Key.get(bindingKey.getTypeLiteral(), annotation));
        }

        @Override
        public void toContextSensitiveProvider(Class<? extends ContextSensitiveProvider<? extends T>> type) {
            toContextSensitiveProvider(Key.get(type));
        }

        @Override
        public void toContextSensitiveProvider(TypeLiteral<? extends ContextSensitiveProvider<? extends T>> type) {
            toContextSensitiveProvider(Key.get(type));
        }

        @Override
        public void toContextSensitiveProvider(Key<? extends ContextSensitiveProvider<? extends T>> key) {
            error.cancel();

            Provider<? extends ContextSensitiveProvider<? extends T>> provider = binder.getProvider(makeUniqueLinkedKey(key));
            binder.bind(bindingKey).toProvider(new ProviderKeyAdapter<>(provider, key));
            binder.bindListener(new BindingMatcher(bindingKey), new Trigger(bindingKey));
        }

        /**
         * For Binder#requireExplicitBindings() support.
         */
        private <U> Key<U> makeUniqueLinkedKey(Key<U> key) {
            Key<U> linkedKey = Key.get(key.getTypeLiteral(), UniqueAnnotations.create());