[sisu-guice] 01/02: Imported Upstream version 3.2.0+dfsg

Eugene Zhukov eugene-guest at moszumanska.debian.org
Tue Mar 25 16:35:27 UTC 2014


This is an automated email from the git hooks/post-receive script.

eugene-guest pushed a commit to branch master
in repository sisu-guice.

commit fe0ddfe80a35146933da35b74f169b729765be1a
Author: Eugene Zhukov <jevgeni.zh at gmail.com>
Date:   Tue Mar 25 14:23:52 2014 +0000

    Imported Upstream version 3.2.0+dfsg
---
 .gitignore                                         |  22 +-
 .../GUICE_618_followup_pipeline_experiment.patch   | 844 +++++++++++++++++++++
 PATCHES/GUICE_697_add_missing_headers.patch        |  50 +-
 .../GUICE_709_externalize_guava_dependency.patch   | 843 --------------------
 PATCHES/GUICE_759_upgrade_to_asm5.patch            |  19 +-
 PATCHES/GUICE_799_fix_osgi_metadata.patch          |  33 +
 PATCHES/SISUFY.patch                               | 116 ++-
 build.xml                                          |   8 +-
 common.xml                                         |   8 +-
 core/pom.xml                                       |  48 +-
 core/src/com/google/inject/Inject.java             |   2 +-
 .../google/inject/binder/LinkedBindingBuilder.java |   7 +
 .../com/google/inject/internal/BindingBuilder.java |   4 +
 .../google/inject/internal/BindingProcessor.java   |  12 +-
 .../InternalFactoryToInitializableAdapter.java     |   5 +-
 .../com/google/inject/internal/InternalFlags.java  |  16 +
 .../internal/ProviderInstanceBindingImpl.java      |  13 +-
 .../com/google/inject/internal/ProviderMethod.java |  23 +-
 .../com/google/inject/internal/RehashableKeys.java |  16 +
 core/src/com/google/inject/spi/ElementSource.java  |  16 +
 core/src/com/google/inject/spi/ModuleSource.java   |  16 +
 .../google/inject/spi/ProviderInstanceBinding.java |   9 +-
 .../google/inject/spi/ProvidesMethodBinding.java   |  40 +
 .../inject/spi/ProvidesMethodTargetVisitor.java    |  37 +
 core/test/com/google/inject/spi/ElementsTest.java  |  58 ++
 .../com/google/inject/spi/ProviderMethodsTest.java |  57 +-
 .../com/google/inject/spi/SpiBindingsTest.java     |   4 +-
 .../com/googlecode/guice/OSGiContainerTest.java    |   2 +-
 extensions/assistedinject/.gitignore               |   1 +
 extensions/assistedinject/build.xml                |   2 +-
 extensions/assistedinject/pom.xml                  |   2 +-
 extensions/grapher/.gitignore                      |   1 +
 extensions/grapher/build.xml                       |   2 +-
 extensions/grapher/pom.xml                         |   2 +-
 .../google/inject/grapher/DefaultNodeCreator.java  |   3 +-
 .../inject/grapher/ShortNameFactoryTest.java       |   2 +-
 extensions/jmx/.gitignore                          |   1 +
 extensions/jmx/build.xml                           |   2 +-
 extensions/jmx/pom.xml                             |  12 +-
 extensions/jndi/.gitignore                         |   1 +
 extensions/jndi/build.xml                          |   2 +-
 extensions/jndi/pom.xml                            |   2 +-
 extensions/mini/.gitignore                         |   1 +
 extensions/multibindings/.gitignore                |   1 +
 extensions/multibindings/build.xml                 |   2 +-
 extensions/multibindings/pom.xml                   |   2 +-
 .../com/google/inject/multibindings/MapBinder.java |  36 +-
 .../google/inject/multibindings/RealElement.java   |   4 +
 .../google/inject/multibindings/MapBinderTest.java |  53 +-
 .../com/google/inject/multibindings/SpiUtils.java  |   4 +-
 extensions/persist/.gitignore                      |   1 +
 extensions/persist/build.xml                       |   2 +-
 extensions/persist/pom.xml                         |  27 +-
 .../inject/persist/jpa/JpaLocalTxnInterceptor.java |   5 +-
 .../test/com/google/inject/persist/EdslTest.java   |   6 +-
 extensions/pom.xml                                 |  43 +-
 extensions/service/.gitignore                      |   1 +
 extensions/servlet/.gitignore                      |   1 +
 extensions/servlet/build.xml                       |   2 +-
 extensions/servlet/pom.xml                         |   2 +-
 ...erPipeline.java => AbstractFilterPipeline.java} |  51 +-
 ...tPipeline.java => AbstractServletPipeline.java} |  46 +-
 .../inject/servlet/FilterChainInvocation.java      |   4 +-
 .../google/inject/servlet/FilterDefinition.java    |  19 +-
 .../src/com/google/inject/servlet/GuiceFilter.java |  26 +-
 .../inject/servlet/InternalServletModule.java      |   7 +-
 .../inject/servlet/ManagedFilterPipeline.java      | 121 +--
 .../inject/servlet/ManagedServletPipeline.java     | 138 +---
 .../google/inject/servlet/ServletDefinition.java   |  22 +-
 .../com/google/inject/servlet/ServletScopes.java   |  21 +-
 .../google/inject/servlet/UriPatternMatcher.java   |   2 +-
 .../com/google/inject/servlet/ServletTest.java     |  45 +-
 extensions/spring/.gitignore                       |   1 +
 extensions/spring/build.xml                        |   2 +-
 extensions/spring/pom.xml                          |   2 +-
 extensions/struts2/.gitignore                      |   1 +
 extensions/struts2/build.xml                       |   2 +-
 extensions/struts2/pom.xml                         |   2 +-
 extensions/throwingproviders/.gitignore            |   1 +
 extensions/throwingproviders/build.xml             |   2 +-
 extensions/throwingproviders/pom.xml               |  14 +-
 guice.iml                                          |   2 +-
 pom.xml                                            |  49 +-
 83 files changed, 1720 insertions(+), 1416 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0380b37..772dff5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,25 +1,9 @@
-# Maven
+/build/
 target/
-*.ser
-*.ec
-
-# Ant
-build/
-!lib/build/
-
-# IntelliJ Idea
-.idea/
-out/
-*.ipr
-*.iws
-*.iml
-
-# Eclipse
-.classpath
+/bin/
 .project
+.classpath
 .settings/
-bin/
-
 *~
 *.orig
 *.new
diff --git a/PATCHES/GUICE_618_followup_pipeline_experiment.patch b/PATCHES/GUICE_618_followup_pipeline_experiment.patch
new file mode 100644
index 0000000..b2ca943
--- /dev/null
+++ b/PATCHES/GUICE_618_followup_pipeline_experiment.patch
@@ -0,0 +1,844 @@
+Description: Experimental refactoring of pipeline and related classes
+Author: Stuart McCulloch <mcculls at gmail.com>
+Bug-Google: http://code.google.com/p/google-guice/issues/detail?id=618
+Last-Update: 2014-03-12
+
+diff --git a/extensions/servlet/src/com/google/inject/servlet/AbstractFilterPipeline.java b/extensions/servlet/src/com/google/inject/servlet/AbstractFilterPipeline.java
+new file mode 100644
+index 0000000..9ab0124
+--- /dev/null
++++ b/extensions/servlet/src/com/google/inject/servlet/AbstractFilterPipeline.java
+@@ -0,0 +1,145 @@
++/**
++ * Copyright (C) 2008 Google Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package com.google.inject.servlet;
++
++import com.google.common.collect.Maps;
++import com.google.common.collect.Sets;
++import com.google.inject.Injector;
++import com.google.inject.Provider;
++
++import java.io.IOException;
++import java.util.Set;
++
++import javax.servlet.Filter;
++import javax.servlet.FilterChain;
++import javax.servlet.RequestDispatcher;
++import javax.servlet.ServletContext;
++import javax.servlet.ServletException;
++import javax.servlet.ServletRequest;
++import javax.servlet.ServletResponse;
++import javax.servlet.http.HttpServletRequest;
++import javax.servlet.http.HttpServletRequestWrapper;
++
++/**
++ * Central routing/dispatch class handles lifecycle of managed filters, and delegates to the servlet
++ * pipeline.
++ *
++ * @author dhanji at gmail.com (Dhanji R. Prasanna)
++ */
++public abstract class AbstractFilterPipeline implements FilterPipeline {
++
++  protected abstract boolean hasFiltersMapped();
++
++  protected abstract FilterDefinition[] filterDefinitions();
++
++  private final AbstractServletPipeline servletPipeline;
++  private final Provider<ServletContext> servletContext;
++
++  //Unfortunately, we need the injector itself in order to create filters + servlets
++  private final Injector injector;
++
++  //Guards a DCL, so needs to be volatile
++  private volatile boolean initialized = false;
++
++  protected AbstractFilterPipeline(Injector injector, AbstractServletPipeline servletPipeline,
++      Provider<ServletContext> servletContext) {
++    this.injector = injector;
++    this.servletPipeline = servletPipeline;
++    this.servletContext = servletContext;
++  }
++
++  public synchronized void initPipeline(ServletContext servletContext)
++      throws ServletException {
++
++    //double-checked lock, prevents duplicate initialization
++    if (initialized)
++      return;
++
++    // Used to prevent duplicate initialization.
++    Set<Filter> initializedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
++
++    for (FilterDefinition filterDefinition : filterDefinitions()) {
++      filterDefinition.init(servletContext, injector, initializedSoFar);
++    }
++
++    //next, initialize servlets...
++    servletPipeline.init(servletContext, injector);
++
++    //everything was ok...
++    initialized = true;
++  }
++
++  public void dispatch(ServletRequest request, ServletResponse response,
++      FilterChain proceedingFilterChain) throws IOException, ServletException {
++
++    //lazy init of filter pipeline (OK by the servlet specification). This is needed
++    //in order for us not to force users to create a GuiceServletContextListener subclass.
++    if (!initialized) {
++      initPipeline(servletContext.get());
++    }
++
++    //obtain the servlet pipeline to dispatch against
++    new FilterChainInvocation(filterDefinitions(), servletPipeline, proceedingFilterChain)
++        .doFilter(withDispatcher(request, servletPipeline), response);
++
++  }
++
++  /**
++   * Used to create an proxy that dispatches either to the guice-servlet pipeline or the regular
++   * pipeline based on uri-path match. This proxy also provides minimal forwarding support.
++   *
++   * We cannot forward from a web.xml Servlet/JSP to a guice-servlet (because the filter pipeline
++   * is not called again). However, we can wrap requests with our own dispatcher to forward the
++   * *other* way. web.xml Servlets/JSPs can forward to themselves as per normal.
++   *
++   * This is not a problem cuz we intend for people to migrate from web.xml to guice-servlet,
++   * incrementally, but not the other way around (which, we should actively discourage).
++   */
++  @SuppressWarnings({ "JavaDoc", "deprecation" })
++  private static ServletRequest withDispatcher(ServletRequest servletRequest,
++      final AbstractServletPipeline servletPipeline) {
++
++    // don't wrap the request if there are no servlets mapped. This prevents us from inserting our
++    // wrapper unless it's actually going to be used. This is necessary for compatibility for apps
++    // that downcast their HttpServletRequests to a concrete implementation.
++    if (!servletPipeline.hasServletsMapped()) {
++      return servletRequest;
++    }
++
++    HttpServletRequest request = (HttpServletRequest) servletRequest;
++    //noinspection OverlyComplexAnonymousInnerClass
++    return new HttpServletRequestWrapper(request) {
++
++      @Override
++      public RequestDispatcher getRequestDispatcher(String path) {
++        final RequestDispatcher dispatcher = servletPipeline.getRequestDispatcher(path);
++
++        return (null != dispatcher) ? dispatcher : super.getRequestDispatcher(path);
++      }
++    };
++  }
++
++  public void destroyPipeline() {
++    //destroy servlets first
++    servletPipeline.destroy();
++
++    //go down chain and destroy all our filters
++    Set<Filter> destroyedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
++    for (FilterDefinition filterDefinition : filterDefinitions()) {
++      filterDefinition.destroy(destroyedSoFar);
++    }
++  }
++}
+diff --git a/extensions/servlet/src/com/google/inject/servlet/AbstractServletPipeline.java b/extensions/servlet/src/com/google/inject/servlet/AbstractServletPipeline.java
+new file mode 100644
+index 0000000..00d849e
+--- /dev/null
++++ b/extensions/servlet/src/com/google/inject/servlet/AbstractServletPipeline.java
+@@ -0,0 +1,158 @@
++/**
++ * Copyright (C) 2008 Google Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++package com.google.inject.servlet;
++
++import com.google.common.base.Preconditions;
++import com.google.common.collect.Maps;
++import com.google.common.collect.Sets;
++import com.google.inject.Injector;
++
++import java.io.IOException;
++import java.util.Set;
++
++import javax.servlet.RequestDispatcher;
++import javax.servlet.ServletContext;
++import javax.servlet.ServletException;
++import javax.servlet.ServletRequest;
++import javax.servlet.ServletResponse;
++import javax.servlet.http.HttpServlet;
++import javax.servlet.http.HttpServletRequest;
++import javax.servlet.http.HttpServletRequestWrapper;
++
++/**
++ * A wrapping dispatcher for servlets, in much the same way as {@link ManagedFilterPipeline} is for
++ * filters.
++ *
++ * @author dhanji at gmail.com (Dhanji R. Prasanna)
++ */
++public abstract class AbstractServletPipeline {
++
++  protected abstract boolean hasServletsMapped();
++
++  protected abstract ServletDefinition[] servletDefinitions();
++
++  public void init(ServletContext servletContext, Injector injector) throws ServletException {
++    Set<HttpServlet> initializedSoFar
++        = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
++
++    for (ServletDefinition servletDefinition : servletDefinitions()) {
++      servletDefinition.init(servletContext, injector, initializedSoFar);
++    }
++  }
++
++  public boolean service(ServletRequest request, ServletResponse response)
++      throws IOException, ServletException {
++
++    //stop at the first matching servlet and service
++    for (ServletDefinition servletDefinition : servletDefinitions()) {
++      if (servletDefinition.service(request, response)) {
++        return true;
++      }
++    }
++
++    //there was no match...
++    return false;
++  }
++
++  public void destroy() {
++    Set<HttpServlet> destroyedSoFar
++        = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
++    for (ServletDefinition servletDefinition : servletDefinitions()) {
++      servletDefinition.destroy(destroyedSoFar);
++    }
++  }
++
++  /**
++   * @return Returns a request dispatcher wrapped with a servlet mapped to
++   * the given path or null if no mapping was found.
++   */
++  RequestDispatcher getRequestDispatcher(String path) {
++    final String newRequestUri = path;
++
++    // TODO(dhanji): check servlet spec to see if the following is legal or not.
++    // Need to strip query string if requested...
++
++    for (final ServletDefinition servletDefinition : servletDefinitions()) {
++      if (servletDefinition.shouldServe(path)) {
++        return new RequestDispatcher() {
++          public void forward(ServletRequest servletRequest, ServletResponse servletResponse)
++              throws ServletException, IOException {
++            Preconditions.checkState(!servletResponse.isCommitted(),
++                "Response has been committed--you can only call forward before"
++                + " committing the response (hint: don't flush buffers)");
++
++            // clear buffer before forwarding
++            servletResponse.resetBuffer();
++
++            ServletRequest requestToProcess;
++            if (servletRequest instanceof HttpServletRequest) {
++               requestToProcess = new RequestDispatcherRequestWrapper(servletRequest, newRequestUri);
++            } else {
++              // This should never happen, but instead of throwing an exception
++              // we will allow a happy case pass thru for maximum tolerance to
++              // legacy (and internal) code.
++              requestToProcess = servletRequest;
++            }
++
++            // now dispatch to the servlet
++            doServiceImpl(servletDefinition, requestToProcess, servletResponse);
++          }
++
++          public void include(ServletRequest servletRequest, ServletResponse servletResponse)
++              throws ServletException, IOException {
++            // route to the target servlet
++            doServiceImpl(servletDefinition, servletRequest, servletResponse);
++          }
++
++          private void doServiceImpl(ServletDefinition servletDefinition, ServletRequest servletRequest,
++              ServletResponse servletResponse) throws ServletException, IOException {
++            servletRequest.setAttribute(REQUEST_DISPATCHER_REQUEST, Boolean.TRUE);
++
++            try {
++              servletDefinition.doService(servletRequest, servletResponse);
++            } finally {
++              servletRequest.removeAttribute(REQUEST_DISPATCHER_REQUEST);
++            }
++          }
++        };
++      }
++    }
++
++    //otherwise, can't process
++    return null;
++  }
++
++  /**
++   * A Marker constant attribute that when present in the request indicates to Guice servlet that
++   * this request has been generated by a request dispatcher rather than the servlet pipeline.
++   * In accordance with section 8.4.2 of the Servlet 2.4 specification.
++   */
++  public static final String REQUEST_DISPATCHER_REQUEST = "javax.servlet.forward.servlet_path";
++
++  private static class RequestDispatcherRequestWrapper extends HttpServletRequestWrapper {
++    private final String newRequestUri;
++
++    public RequestDispatcherRequestWrapper(ServletRequest servletRequest, String newRequestUri) {
++      super((HttpServletRequest) servletRequest);
++      this.newRequestUri = newRequestUri;
++    }
++
++    @Override
++    public String getRequestURI() {
++      return newRequestUri;
++    }
++  }
++}
+diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
+index b4112cf..bfe5a83 100644
+--- a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
++++ b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
+@@ -50,7 +50,7 @@ class FilterChainInvocation implements FilterChain {
+   
+   private final FilterDefinition[] filterDefinitions;
+   private final FilterChain proceedingChain;
+-  private final ManagedServletPipeline servletPipeline;
++  private final AbstractServletPipeline servletPipeline;
+ 
+   //state variable tracks current link in filterchain
+   private int index = -1;
+@@ -58,7 +58,7 @@ class FilterChainInvocation implements FilterChain {
+   private boolean cleanedStacks = false;
+ 
+   public FilterChainInvocation(FilterDefinition[] filterDefinitions,
+-      ManagedServletPipeline servletPipeline, FilterChain proceedingChain) {
++      AbstractServletPipeline servletPipeline, FilterChain proceedingChain) {
+ 
+     this.filterDefinitions = filterDefinitions;
+     this.servletPipeline = servletPipeline;
+diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
+index ff1e5b6..0bfdadd 100644
+--- a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
++++ b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
+@@ -15,6 +15,7 @@
+  */
+ package com.google.inject.servlet;
+ 
++import com.google.common.base.Strings;
+ import com.google.common.collect.Iterators;
+ import com.google.inject.Injector;
+ import com.google.inject.Key;
+@@ -29,6 +30,8 @@ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.atomic.AtomicReference;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ 
+ import javax.servlet.Filter;
+ import javax.servlet.FilterConfig;
+@@ -41,7 +44,9 @@ import javax.servlet.http.HttpServletRequest;
+  *
+  * @author dhanji at gmail.com (Dhanji R. Prasanna)
+  */
+-class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition> {
++public class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition> {
++  private static final Logger logger = Logger.getLogger(FilterDefinition.class.getName());
++
+   private final String pattern;
+   private final Key<? extends Filter> filterKey;
+   private final UriPatternMatcher patternMatcher;
+@@ -154,7 +159,11 @@ class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition>
+ 
+     final String path = ServletUtils.getContextRelativePath(request);
+     if (shouldFilter(path)) {
+-      return filter.get();
++      Filter reference = filter.get();
++      if (logger.isLoggable(Level.FINEST)) {
++        logger.finest("Filtering " + path + " with " + reference);
++      }
++      return reference;
+     } else {
+       return null;
+     }
+@@ -164,4 +173,10 @@ class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition>
+   Filter getFilter() {
+     return filter.get();
+   }
++
++  public String toPaddedString(int padding) {
++    Filter reference = filter.get();
++    return Strings.padEnd(pattern, padding, ' ') + ' '
++        + (reference != null ? reference : filterKey);
++  }
+ }
+diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java b/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
+index 9e5b849..47bfec9 100644
+--- a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
++++ b/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
+@@ -16,8 +16,6 @@
+ package com.google.inject.servlet;
+ 
+ import com.google.common.collect.Lists;
+-import com.google.common.collect.Maps;
+-import com.google.common.collect.Sets;
+ import com.google.inject.Binding;
+ import com.google.inject.Inject;
+ import com.google.inject.Injector;
+@@ -25,19 +23,9 @@ import com.google.inject.Provider;
+ import com.google.inject.Singleton;
+ import com.google.inject.TypeLiteral;
+ 
+-import java.io.IOException;
+ import java.util.List;
+-import java.util.Set;
+ 
+-import javax.servlet.Filter;
+-import javax.servlet.FilterChain;
+-import javax.servlet.RequestDispatcher;
+ import javax.servlet.ServletContext;
+-import javax.servlet.ServletException;
+-import javax.servlet.ServletRequest;
+-import javax.servlet.ServletResponse;
+-import javax.servlet.http.HttpServletRequest;
+-import javax.servlet.http.HttpServletRequestWrapper;
+ 
+ /**
+  * Central routing/dispatch class handles lifecycle of managed filters, and delegates to the servlet
+@@ -46,29 +34,28 @@ import javax.servlet.http.HttpServletRequestWrapper;
+  * @author dhanji at gmail.com (Dhanji R. Prasanna)
+  */
+ @Singleton
+-class ManagedFilterPipeline implements FilterPipeline{
++class ManagedFilterPipeline extends AbstractFilterPipeline {
+   private final FilterDefinition[] filterDefinitions;
+-  private final ManagedServletPipeline servletPipeline;
+-  private final Provider<ServletContext> servletContext;
+-
+-  //Unfortunately, we need the injector itself in order to create filters + servlets
+-  private final Injector injector;
+-
+-  //Guards a DCL, so needs to be volatile
+-  private volatile boolean initialized = false;
+   private static final TypeLiteral<FilterDefinition> FILTER_DEFS =
+       TypeLiteral.get(FilterDefinition.class);
+ 
+   @Inject
+   public ManagedFilterPipeline(Injector injector, ManagedServletPipeline servletPipeline,
+       Provider<ServletContext> servletContext) {
+-    this.injector = injector;
+-    this.servletPipeline = servletPipeline;
+-    this.servletContext = servletContext;
+-
++    super(injector, servletPipeline, servletContext);
+     this.filterDefinitions = collectFilterDefinitions(injector);
+   }
+ 
++  @Override
++  protected boolean hasFiltersMapped() {
++    return filterDefinitions.length > 0;
++  }
++
++  @Override
++  protected FilterDefinition[] filterDefinitions() {
++    return filterDefinitions;
++  }
++
+   /**
+    * Introspects the injector and collects all instances of bound {@code List<FilterDefinition>}
+    * into a master list.
+@@ -76,7 +63,7 @@ class ManagedFilterPipeline implements FilterPipeline{
+    * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
+    * that preserves insertion order in entry-set iterators.
+    */
+-  private FilterDefinition[] collectFilterDefinitions(Injector injector) {
++  private static FilterDefinition[] collectFilterDefinitions(Injector injector) {
+     List<FilterDefinition> filterDefinitions = Lists.newArrayList();
+     for (Binding<FilterDefinition> entry : injector.findBindingsByType(FILTER_DEFS)) {
+       filterDefinitions.add(entry.getProvider().get());
+@@ -85,86 +72,4 @@ class ManagedFilterPipeline implements FilterPipeline{
+     // Copy to a fixed-size array for speed of iteration.
+     return filterDefinitions.toArray(new FilterDefinition[filterDefinitions.size()]);
+   }
+-
+-  public synchronized void initPipeline(ServletContext servletContext)
+-      throws ServletException {
+-
+-    //double-checked lock, prevents duplicate initialization
+-    if (initialized)
+-      return;
+-
+-    // Used to prevent duplicate initialization.
+-    Set<Filter> initializedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
+-
+-    for (FilterDefinition filterDefinition : filterDefinitions) {
+-      filterDefinition.init(servletContext, injector, initializedSoFar);
+-    }
+-
+-    //next, initialize servlets...
+-    servletPipeline.init(servletContext, injector);
+-
+-    //everything was ok...
+-    initialized = true;
+-  }
+-
+-  public void dispatch(ServletRequest request, ServletResponse response,
+-      FilterChain proceedingFilterChain) throws IOException, ServletException {
+-
+-    //lazy init of filter pipeline (OK by the servlet specification). This is needed
+-    //in order for us not to force users to create a GuiceServletContextListener subclass.
+-    if (!initialized) {
+-      initPipeline(servletContext.get());
+-    }
+-
+-    //obtain the servlet pipeline to dispatch against
+-    new FilterChainInvocation(filterDefinitions, servletPipeline, proceedingFilterChain)
+-        .doFilter(withDispatcher(request, servletPipeline), response);
+-
+-  }
+-
+-  /**
+-   * Used to create an proxy that dispatches either to the guice-servlet pipeline or the regular
+-   * pipeline based on uri-path match. This proxy also provides minimal forwarding support.
+-   *
+-   * We cannot forward from a web.xml Servlet/JSP to a guice-servlet (because the filter pipeline
+-   * is not called again). However, we can wrap requests with our own dispatcher to forward the
+-   * *other* way. web.xml Servlets/JSPs can forward to themselves as per normal.
+-   *
+-   * This is not a problem cuz we intend for people to migrate from web.xml to guice-servlet,
+-   * incrementally, but not the other way around (which, we should actively discourage).
+-   */
+-  @SuppressWarnings({ "JavaDoc", "deprecation" })
+-  private ServletRequest withDispatcher(ServletRequest servletRequest,
+-      final ManagedServletPipeline servletPipeline) {
+-
+-    // don't wrap the request if there are no servlets mapped. This prevents us from inserting our
+-    // wrapper unless it's actually going to be used. This is necessary for compatibility for apps
+-    // that downcast their HttpServletRequests to a concrete implementation.
+-    if (!servletPipeline.hasServletsMapped()) {
+-      return servletRequest;
+-    }
+-
+-    HttpServletRequest request = (HttpServletRequest) servletRequest;
+-    //noinspection OverlyComplexAnonymousInnerClass
+-    return new HttpServletRequestWrapper(request) {
+-
+-      @Override
+-      public RequestDispatcher getRequestDispatcher(String path) {
+-        final RequestDispatcher dispatcher = servletPipeline.getRequestDispatcher(path);
+-
+-        return (null != dispatcher) ? dispatcher : super.getRequestDispatcher(path);
+-      }
+-    };
+-  }
+-
+-  public void destroyPipeline() {
+-    //destroy servlets first
+-    servletPipeline.destroy();
+-
+-    //go down chain and destroy all our filters
+-    Set<Filter> destroyedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
+-    for (FilterDefinition filterDefinition : filterDefinitions) {
+-      filterDefinition.destroy(destroyedSoFar);
+-    }
+-  }
+ }
+diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java b/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
+index e3e35df..3530c06 100644
+--- a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
++++ b/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
+@@ -15,28 +15,14 @@
+  */
+ package com.google.inject.servlet;
+ 
+-import com.google.common.base.Preconditions;
+ import com.google.common.collect.Lists;
+-import com.google.common.collect.Maps;
+-import com.google.common.collect.Sets;
+ import com.google.inject.Binding;
+ import com.google.inject.Inject;
+ import com.google.inject.Injector;
+ import com.google.inject.Singleton;
+ import com.google.inject.TypeLiteral;
+ 
+-import java.io.IOException;
+ import java.util.List;
+-import java.util.Set;
+-
+-import javax.servlet.RequestDispatcher;
+-import javax.servlet.ServletContext;
+-import javax.servlet.ServletException;
+-import javax.servlet.ServletRequest;
+-import javax.servlet.ServletResponse;
+-import javax.servlet.http.HttpServlet;
+-import javax.servlet.http.HttpServletRequest;
+-import javax.servlet.http.HttpServletRequestWrapper;
+ 
+ /**
+  * A wrapping dispatcher for servlets, in much the same way as {@link ManagedFilterPipeline} is for
+@@ -45,7 +31,7 @@ import javax.servlet.http.HttpServletRequestWrapper;
+  * @author dhanji at gmail.com (Dhanji R. Prasanna)
+  */
+ @Singleton
+-class ManagedServletPipeline {
++class ManagedServletPipeline extends AbstractServletPipeline {
+   private final ServletDefinition[] servletDefinitions;
+   private static final TypeLiteral<ServletDefinition> SERVLET_DEFS =
+       TypeLiteral.get(ServletDefinition.class);
+@@ -55,10 +41,16 @@ class ManagedServletPipeline {
+     this.servletDefinitions = collectServletDefinitions(injector);
+   }
+ 
+-  boolean hasServletsMapped() {
++  @Override
++  protected boolean hasServletsMapped() {
+     return servletDefinitions.length > 0;
+   }
+ 
++  @Override
++  protected ServletDefinition[] servletDefinitions() {
++    return servletDefinitions;
++  }
++
+   /**
+    * Introspects the injector and collects all instances of bound {@code List<ServletDefinition>}
+    * into a master list.
+@@ -66,7 +58,7 @@ class ManagedServletPipeline {
+    * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
+    * that preserves insertion order in entry-set iterators.
+    */
+-  private ServletDefinition[] collectServletDefinitions(Injector injector) {
++  private static ServletDefinition[] collectServletDefinitions(Injector injector) {
+     List<ServletDefinition> servletDefinitions = Lists.newArrayList();
+     for (Binding<ServletDefinition> entry : injector.findBindingsByType(SERVLET_DEFS)) {
+         servletDefinitions.add(entry.getProvider().get());
+@@ -75,116 +67,4 @@ class ManagedServletPipeline {
+     // Copy to a fixed size array for speed.
+     return servletDefinitions.toArray(new ServletDefinition[servletDefinitions.size()]);
+   }
+-
+-  public void init(ServletContext servletContext, Injector injector) throws ServletException {
+-    Set<HttpServlet> initializedSoFar
+-        = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
+-
+-    for (ServletDefinition servletDefinition : servletDefinitions) {
+-      servletDefinition.init(servletContext, injector, initializedSoFar);
+-    }
+-  }
+-
+-  public boolean service(ServletRequest request, ServletResponse response)
+-      throws IOException, ServletException {
+-
+-    //stop at the first matching servlet and service
+-    for (ServletDefinition servletDefinition : servletDefinitions) {
+-      if (servletDefinition.service(request, response)) {
+-        return true;
+-      }
+-    }
+-
+-    //there was no match...
+-    return false;
+-  }
+-
+-  public void destroy() {
+-    Set<HttpServlet> destroyedSoFar
+-        = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
+-    for (ServletDefinition servletDefinition : servletDefinitions) {
+-      servletDefinition.destroy(destroyedSoFar);
+-    }
+-  }
+-
+-  /**
+-   * @return Returns a request dispatcher wrapped with a servlet mapped to
+-   * the given path or null if no mapping was found.
+-   */
+-  RequestDispatcher getRequestDispatcher(String path) {
+-    final String newRequestUri = path;
+-
+-    // TODO(dhanji): check servlet spec to see if the following is legal or not.
+-    // Need to strip query string if requested...
+-
+-    for (final ServletDefinition servletDefinition : servletDefinitions) {
+-      if (servletDefinition.shouldServe(path)) {
+-        return new RequestDispatcher() {
+-          public void forward(ServletRequest servletRequest, ServletResponse servletResponse)
+-              throws ServletException, IOException {
+-            Preconditions.checkState(!servletResponse.isCommitted(),
+-                "Response has been committed--you can only call forward before"
+-                + " committing the response (hint: don't flush buffers)");
+-
+-            // clear buffer before forwarding
+-            servletResponse.resetBuffer();
+-
+-            ServletRequest requestToProcess;
+-            if (servletRequest instanceof HttpServletRequest) {
+-               requestToProcess = new RequestDispatcherRequestWrapper(servletRequest, newRequestUri);
+-            } else {
+-              // This should never happen, but instead of throwing an exception
+-              // we will allow a happy case pass thru for maximum tolerance to
+-              // legacy (and internal) code.
+-              requestToProcess = servletRequest;
+-            }
+-
+-            // now dispatch to the servlet
+-            doServiceImpl(servletDefinition, requestToProcess, servletResponse);
+-          }
+-
+-          public void include(ServletRequest servletRequest, ServletResponse servletResponse)
+-              throws ServletException, IOException {
+-            // route to the target servlet
+-            doServiceImpl(servletDefinition, servletRequest, servletResponse);
+-          }
+-
+-          private void doServiceImpl(ServletDefinition servletDefinition, ServletRequest servletRequest,
+-              ServletResponse servletResponse) throws ServletException, IOException {
+-            servletRequest.setAttribute(REQUEST_DISPATCHER_REQUEST, Boolean.TRUE);
+-
+-            try {
+-              servletDefinition.doService(servletRequest, servletResponse);
+-            } finally {
+-              servletRequest.removeAttribute(REQUEST_DISPATCHER_REQUEST);
+-            }
+-          }
+-        };
+-      }
+-    }
+-
+-    //otherwise, can't process
+-    return null;
+-  }
+-
+-  /**
+-   * A Marker constant attribute that when present in the request indicates to Guice servlet that
+-   * this request has been generated by a request dispatcher rather than the servlet pipeline.
+-   * In accordance with section 8.4.2 of the Servlet 2.4 specification.
+-   */
+-  public static final String REQUEST_DISPATCHER_REQUEST = "javax.servlet.forward.servlet_path";
+-
+-  private static class RequestDispatcherRequestWrapper extends HttpServletRequestWrapper {
+-    private final String newRequestUri;
+-
+-    public RequestDispatcherRequestWrapper(ServletRequest servletRequest, String newRequestUri) {
+-      super((HttpServletRequest) servletRequest);
+-      this.newRequestUri = newRequestUri;
+-    }
+-
+-    @Override
+-    public String getRequestURI() {
+-      return newRequestUri;
+-    }
+-  }
+ }
+diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java b/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
+index cbd8f29..b968aa7 100644
+--- a/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
++++ b/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
+@@ -17,6 +17,7 @@ package com.google.inject.servlet;
+ 
+ import static com.google.inject.servlet.ManagedServletPipeline.REQUEST_DISPATCHER_REQUEST;
+ 
++import com.google.common.base.Strings;
+ import com.google.common.collect.Iterators;
+ import com.google.inject.Injector;
+ import com.google.inject.Key;
+@@ -34,6 +35,8 @@ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.concurrent.atomic.AtomicReference;
++import java.util.logging.Level;
++import java.util.logging.Logger;
+ 
+ import javax.servlet.ServletConfig;
+ import javax.servlet.ServletContext;
+@@ -51,7 +54,9 @@ import javax.servlet.http.HttpServletResponse;
+  *
+  * @author dhanji at gmail.com (Dhanji R. Prasanna)
+  */
+-class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinition> {
++public class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinition> {
++  private static final Logger logger = Logger.getLogger(ServletDefinition.class.getName());
++
+   private final String pattern;
+   private final Key<? extends HttpServlet> servletKey;
+   private final UriPatternMatcher patternMatcher;
+@@ -285,7 +290,14 @@ class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinitio
+         = (previous != null) ? previous.getOriginalRequest() : request;
+     GuiceFilter.localContext.set(new GuiceFilter.Context(originalRequest, request, response));
+     try {
+-      httpServlet.get().service(request, response);
++      HttpServlet reference = httpServlet.get();
++      if (logger.isLoggable(Level.FINEST)) {
++        String path = ServletUtils.getContextRelativePath(request);
++        logger.finest("Serving " + path + " with " + reference);
++      }
++      if (reference != null) {
++        reference.service(request, response);
++      }
+     } finally {
+       GuiceFilter.localContext.set(previous);
+     }
+@@ -298,4 +310,10 @@ class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinitio
+   String getPattern() {
+     return pattern;
+   }
++
++  public String toPaddedString(int padding) {
++    HttpServlet reference = httpServlet.get();
++    return Strings.padEnd(pattern, padding, ' ') + ' '
++        + (reference != null ? reference : servletKey);
++  }
+ }
+diff --git a/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java b/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
+index d8bac74..169dd89 100644
+--- a/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
++++ b/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
+@@ -22,7 +22,7 @@ package com.google.inject.servlet;
+  *
+  * @author dhanji at gmail.com (Dhanji R. Prasanna)
+  */
+-interface UriPatternMatcher {
++public interface UriPatternMatcher {
+   /**
+    * @param uri A "contextual" (i.e. relative) Request URI, *not* a complete one.
+    * @return Returns true if the uri matches the pattern.
+diff --git a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java b/extensions/servlet/src/com/google/injec
+index f7a108f..7ab0cdf 100644
+--- a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
++++ b/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
+@@ -100,9 +100,9 @@ public class GuiceFilter implements Filter {
+ 
+     // This can happen if you create many injectors and they all have their own
+     // servlet module. This is legal, caveat a small warning.
+-    if (GuiceFilter.pipeline instanceof ManagedFilterPipeline) {
+-      LOGGER.config(MULTIPLE_INJECTORS_WARNING);
+-    }
++    //if (GuiceFilter.pipeline instanceof ManagedFilterPipeline) {
++    //  LOGGER.config(MULTIPLE_INJECTORS_WARNING);
++    //}
+ 
+     // We overwrite the default pipeline
+     GuiceFilter.pipeline = pipeline;
diff --git a/PATCHES/GUICE_697_add_missing_headers.patch b/PATCHES/GUICE_697_add_missing_headers.patch
index 6d0ac38..a45c652 100644
--- a/PATCHES/GUICE_697_add_missing_headers.patch
+++ b/PATCHES/GUICE_697_add_missing_headers.patch
@@ -1,7 +1,7 @@
 Description: Add missing headers (codebase is licensed under the Apache License, Version 2.0)
 Author: Stuart McCulloch <mcculls at gmail.com>
 Bug-Google: http://code.google.com/p/google-guice/issues/detail?id=697
-Last-Update: 2014-01-20
+Last-Update: 2014-03-14
 
 diff --git a/core/src/com/google/inject/internal/DelayedInitialize.java b/core/src/com/google/inject/internal/DelayedInitialize.java
 index 80e52d1..82a8463 100644
@@ -293,3 +293,51 @@ index 4b87f40..79df84d 100644
  
  package com.google.inject.throwingproviders;
  
+diff --git a/core/src/com/google/inject/spi/ProvidesMethodBinding.java b/core/src/com/google/inject/spi/ProvidesMethodBinding.java
+index f35d9a4..0429834 100644
+--- a/core/src/com/google/inject/spi/ProvidesMethodBinding.java
++++ b/core/src/com/google/inject/spi/ProvidesMethodBinding.java
+@@ -1,3 +1,19 @@
++/**
++ * Copyright (C) 2013 Google Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
+ package com.google.inject.spi;
+ 
+ import com.google.inject.Key;
+diff --git a/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java b/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
+index d6c4973..d42ba95 100644
+--- a/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
++++ b/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
+@@ -1,3 +1,19 @@
++/**
++ * Copyright (C) 2013 Google Inc.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
+ package com.google.inject.spi;
+ 
+ import com.google.inject.Provides;
diff --git a/PATCHES/GUICE_709_externalize_guava_dependency.patch b/PATCHES/GUICE_709_externalize_guava_dependency.patch
deleted file mode 100644
index 6681216..0000000
--- a/PATCHES/GUICE_709_externalize_guava_dependency.patch
+++ /dev/null
@@ -1,843 +0,0 @@
-Description: Pull out embedded Guava and expose it as an external dependency
-Author: Stuart McCulloch <mcculls at gmail.com>
-Bug-Google: http://code.google.com/p/google-guice/issues/detail?id=709
-Last-Update: 2014-01-17
-
-diff --git a/build.properties b/build.properties
-index a76a5ab..d8bf543 100644
---- a/build.properties
-+++ b/build.properties
-@@ -32,4 +32,4 @@ javadoc.packagenames=com.google.inject,com.google.inject.spi,\
-   com.google.inject.persist.jpa
- test.class=com.google.inject.AllTests
- module=com.google.inject
--imports=!net.sf.cglib.*,!org.objectweb.asm.*,!com.google.common.*
-+imports=!net.sf.cglib.*,!org.objectweb.asm.*
-diff --git a/build.xml b/build.xml
-index 51d2cb1..d9802ae 100644
---- a/build.xml
-+++ b/build.xml
-@@ -31,34 +31,34 @@
-         <ant antfile="extensions/grapher/build.xml" target="distjars" inheritAll="false"/>
- 
-     <copy toDir="${build.dir}/dist"> 
--      <fileset dir="extensions/servlet/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/servlet/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist"> 
--      <fileset dir="extensions/spring/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/spring/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist">
--      <fileset dir="extensions/struts2/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/struts2/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist">
--      <fileset dir="extensions/assistedinject/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/assistedinject/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist">
--      <fileset dir="extensions/jmx/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/jmx/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist">
--      <fileset dir="extensions/jndi/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/jndi/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist">
--      <fileset dir="extensions/throwingproviders/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/throwingproviders/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist">
--      <fileset dir="extensions/multibindings/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/multibindings/build" includes="*.jar"/>
-     </copy>
-     <copy toDir="${build.dir}/dist">
--      <fileset dir="extensions/persist/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+      <fileset dir="extensions/persist/build" includes="*.jar"/>
-     </copy>
-         <copy toDir="${build.dir}/dist">
--          <fileset dir="extensions/grapher/build" includes="*.jar" excludes="*-with-deps.jar"/>
-+          <fileset dir="extensions/grapher/build" includes="*.jar"/>
-         </copy>
- 
-     <copy toDir="${build.dir}/dist" file="COPYING"/> 
-@@ -93,7 +93,7 @@
-   </target>
- 
-   <target name="test.dist.run"
--    depends="jar, test.compile-with-deps"
-+    depends="jar, test.withdeps"
-     description="Execute JUnit tests against distribution jar with the given jvmarg.">
-     <java fork="true"
-         classname="junit.textui.TestRunner"
-@@ -102,11 +102,12 @@
-       <classpath>
-         <pathelement location="${build.dir}/guice-${version}-tests.jar"/>
-         <pathelement location="${build.dir}/dist/guice-${version}.jar"/>
-+        <pathelement location="lib/javax.inject.jar"/>
-         <pathelement location="lib/aopalliance.jar"/>
-+        <pathelement location="lib/guava-11.0.2.jar"/>
-         <pathelement location="lib/build/junit.jar"/>
-         <pathelement location="lib/build/servlet-api-2.5.jar"/>
-         <pathelement location="lib/build/easymock.jar"/>
--        <pathelement location="lib/javax.inject.jar"/>
-         <pathelement location="lib/build/javax.inject-tck.jar"/>
-         <pathelement location="lib/build/bnd-0.0.384.jar"/>
-         <pathelement location="lib/build/felix-2.0.5.jar"/>
-@@ -134,7 +135,7 @@
-     <javadoc packagenames="com.google.*"
-                  docletpath="${jdiff.home}/jdiff.jar${path.separator}${jdiff.home}/xerces.jar"
-              maxmemory="512M"
--             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar">
-+             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}guava-11.0.2.jar">
-       <fileset dir="${src.dir}" defaultexcludes="yes">
-         <include name="com/google/**"/>
-         <exclude name="com/google/inject/internal/**"/>
-@@ -163,7 +164,7 @@
-                      docletpath="${jdiff.home}/jdiff.jar${path.separator}${jdiff.home}/xerces.jar"
-                  maxmemory="512M"
-                      sourcefiles="${jdiff.home}/Null.java"
--                 classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar">
-+                 classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}guava-11.0.2.jar">
-           <doclet name="jdiff.JDiff">
-                 <param name="-oldapi" value="${old.api}"/>
-                 <param name="-oldapidir" value="latest-api-diffs"/>             
-@@ -183,7 +184,7 @@
-              docletpath="lib/build/doclava.jar"
-              bootclasspath="${java.home}/lib/rt.jar"
-              maxmemory="512M"
--             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar">
-+             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}guava-11.0.2.jar">
-       <fileset dir="${src.dir}" defaultexcludes="yes">
-         <include name="com/google/**"/>
-         <exclude name="com/google/inject/internal/**"/>
-diff --git a/common.xml b/common.xml
-index 1a7add9..e54d19d 100644
---- a/common.xml
-+++ b/common.xml
-@@ -119,7 +119,7 @@
-       depends="source.jar, jar"
-       description="Build jar files"/>
- 
--  <target name="test.compile-with-deps" depends="test.compile"
-+  <target name="test.withdeps" depends="test.compile"
-       description="Build a jar of tests with internal.util refocused.">
-     <mkdir dir="${build.dir}/dist"/>
-     <dirname property="common.basedir" file="${ant.file.common}"/>
-@@ -131,10 +131,6 @@
-       <rule pattern="net.sf.cglib.**.*" result="com.google.inject.internal.cglib. at 1.$@2"/>
-       <rule pattern="org.objectweb.asm.*" result="com.google.inject.internal.asm.$@1"/>
-       <rule pattern="org.objectweb.asm.**.*" result="com.google.inject.internal.asm. at 1.$@2"/>
--      <rule pattern="com.google.common.*" result="com.google.inject.internal.guava.$@1"/>
--      <rule pattern="com.google.common.**.*" result="com.google.inject.internal.guava. at 1.$@2"/>
--      <rule pattern="javax.annotation.*.class" result="com.google.inject.internal.jsr305.$@1"/>
--      <rule pattern="javax.annotation.**.*.class" result="com.google.inject.internal.jsr305. at 1.$@2"/>
-       <keep pattern="com.google.inject.**"/>
-       <keep pattern="com.googlecode.**"/>
-     </jarjar>
-@@ -150,35 +146,10 @@
-       <fileset dir="${build.dir}/classes"/>
-       <zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"/>
-       <zipfileset src="${common.basedir}/lib/build/asm-4.2.jar"/>
--      <zipfileset src="${common.basedir}/lib/build/guava-11.0.1.jar"/>
-       <rule pattern="net.sf.cglib.*" result="com.google.inject.internal.cglib.$@1"/>
-       <rule pattern="net.sf.cglib.**.*" result="com.google.inject.internal.cglib. at 1.$@2"/>
-       <rule pattern="org.objectweb.asm.*" result="com.google.inject.internal.asm.$@1"/>
-       <rule pattern="org.objectweb.asm.**.*" result="com.google.inject.internal.asm. at 1.$@2"/>
--      <rule pattern="com.google.common.*" result="com.google.inject.internal.guava.$@1"/>
--      <rule pattern="com.google.common.**.*" result="com.google.inject.internal.guava. at 1.$@2"/>
--      <keep pattern="com.google.inject.**"/>
--      <!-- the servlet extension uses this but core doesn't,
--           so we explicitly instruct the build to keep it. -->
--      <keep pattern="com.google.common.base.Throwables"/>
--    </jarjar>
--  </target>
--
--  <target name="jar.withrenameddeps" depends="compile"
--      description="Build jar with dependencies embedded.">
--    <mkdir dir="${build.dir}/dist"/>
--    <dirname property="common.basedir" file="${ant.file.common}"/>
--    <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
--        classpath="${common.basedir}/lib/build/jarjar-1.1.jar"/>
--    <jarjar jarfile="${build.dir}/${ant.project.name}-with-deps.jar">
--      <zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"><include name="LICENSE"/><include name="NOTICE"/></zipfileset>
--      <fileset dir="${build.dir}/classes"/>
--      <rule pattern="net.sf.cglib.*" result="com.google.inject.internal.cglib.$@1"/>
--      <rule pattern="net.sf.cglib.**.*" result="com.google.inject.internal.cglib. at 1.$@2"/>
--      <rule pattern="org.objectweb.asm.*" result="com.google.inject.internal.asm.$@1"/>
--      <rule pattern="org.objectweb.asm.**.*" result="com.google.inject.internal.asm. at 1.$@2"/>
--      <rule pattern="com.google.common.*" result="com.google.inject.internal.guava.$@1"/>
--      <rule pattern="com.google.common.**.*" result="com.google.inject.internal.guava. at 1.$@2"/>
-       <keep pattern="com.google.inject.**"/>
-     </jarjar>
-   </target>
-diff --git a/copy.sh b/copy.sh
-deleted file mode 100755
-index a3e2202..0000000
---- a/copy.sh
-+++ /dev/null
-@@ -1,54 +0,0 @@
--#!/bin/sh
--# Copies classes into Guice's internal package.
--
--client=/usr/local/google/clients/collect/google3
--
--srcdir=core/src/com/google/inject/internal
--testdir=core/test/com/google/inject/internal
--
--filter() {
--  sed 's/com.google.common.base.internal/com.google.inject.internal/' | \
--  sed 's/com.google.common.base/com.google.inject.internal/' | \
--  sed 's/com.google.common.collect/com.google.inject.internal/'
--}
--
--copy() {
--  inFile=$1;
--  fileName=`basename $inFile`
--  dest=$2
--  destpath=$dest/$fileName
--  filter < $client/${inFile} > $destpath
--}
--
--commonpath=java/com/google/common
--
--copy $commonpath/collect/ComputationException.java $srcdir
--copy $commonpath/collect/AsynchronousComputationException.java $srcdir
--copy $commonpath/collect/CustomConcurrentHashMap.java $srcdir
--copy $commonpath/collect/ExpirationTimer.java $srcdir
--copy $commonpath/collect/MapMaker.java $srcdir
--copy $commonpath/collect/NullOutputException.java $srcdir
--copy $commonpath/base/Function.java $srcdir
--copy $commonpath/base/Nullable.java $srcdir
--copy $commonpath/base/FinalizableReference.java $srcdir
--copy $commonpath/base/FinalizableReferenceQueue.java $srcdir
--copy $commonpath/base/internal/Finalizer.java $srcdir
--copy $commonpath/base/FinalizableWeakReference.java $srcdir
--copy $commonpath/base/FinalizableSoftReference.java $srcdir
--copy $commonpath/base/FinalizablePhantomReference.java $srcdir
--
--commontestspath=javatests/com/google/common
--
--copy $commontestspath/base/FinalizableReferenceQueueTest.java $testdir
--copy $commontestspath/collect/MapMakerTestSuite.java $testdir
--copy $commontestspath/collect/Jsr166HashMap.java $testdir
--copy $commontestspath/collect/Jsr166HashMapTest.java $testdir
--copy $commonpath/collect/ForwardingConcurrentMap.java $testdir
--copy $commonpath/collect/ForwardingMap.java $testdir
--copy $commonpath/collect/ForwardingCollection.java $testdir
--copy $commonpath/collect/ForwardingObject.java $testdir
--copy $commonpath/collect/ForwardingSet.java $testdir
--copy $commonpath/collect/ForwardingMap.java $testdir
--copy $commonpath/base/Preconditions.java $testdir
--
--chmod +w -R $srcdir $testdir
-diff --git a/core/pom.xml b/core/pom.xml
-index 97c8e60..1ea34a2 100644
---- a/core/pom.xml
-+++ b/core/pom.xml
-@@ -13,11 +13,6 @@
- 
-   <name>Google Guice - Core Library</name>
- 
--  <properties>
--    <cglib.version>3.0</cglib.version>
--    <asm.version>4.0</asm.version>
--  </properties>
--
-   <dependencies>
-     <dependency>
-       <groupId>javax.inject</groupId>
-@@ -32,17 +27,17 @@
-     <dependency>
-       <groupId>com.google.guava</groupId>
-       <artifactId>guava</artifactId>
--      <version>11.0.1</version>
-+      <version>11.0.2</version>
-     </dependency>
-+    <!--
-+     | CGLIB is embedded by default by the JarJar build profile
-+    -->
-     <dependency>
-       <groupId>cglib</groupId>
-       <artifactId>cglib</artifactId>
--      <version>${cglib.version}</version>
--    </dependency>
--    <dependency>
--      <groupId>org.ow2.asm</groupId>
--      <artifactId>asm-util</artifactId>
--      <version>${asm.version}</version>
-+      <version>3.1</version>
-+      <optional>true</optional>
-+      <scope>provided</scope>
-     </dependency>
-     <dependency>
-       <groupId>javax.inject</groupId>
-@@ -207,7 +202,7 @@
-     </profile>
-     <profile>
-       <!--
--       | JarJar build profile: re-package ASM and CGLIB classes under the Guice namespace
-+       | JarJar build profile: embed CGLIB (and ASM) classes under Guice namespace
-       -->
-       <id>guice.with.jarjar</id>
-       <activation>
-@@ -216,52 +211,87 @@
-           <value>!false</value>
-         </property>
-       </activation>
--      <dependencies>
--        <!--
--         | Mark as optional: embedded by JarJar
--        -->
--        <dependency>
--          <groupId>cglib</groupId>
--          <artifactId>cglib</artifactId>
--          <version>${cglib.version}</version>
--          <optional>true</optional>
--        </dependency>
--        <dependency>
--          <groupId>org.ow2.asm</groupId>
--          <artifactId>asm-util</artifactId>
--          <version>${asm.version}</version>
--          <optional>true</optional>
--        </dependency>
--      </dependencies>
-       <build>
-         <plugins>
-           <plugin>
-             <groupId>org.sonatype.plugins</groupId>
-             <artifactId>jarjar-maven-plugin</artifactId>
-+            <version>1.8</version>
-             <configuration>
-+              <overwrite>true</overwrite>
-               <includes>
-                 <include>*:asm*</include>
-                 <include>*:cglib</include>
--                <include>*:guava</include>
--                <include>*:jsr305</include>
-               </includes>
-+              <rules>
-+                <rule>
-+                  <pattern>net.sf.cglib.*</pattern>
-+                  <result>com.google.inject.internal.cglib.$@1</result>
-+                </rule>
-+                <rule>
-+                  <pattern>net.sf.cglib.**.*</pattern>
-+                  <result>com.google.inject.internal.cglib. at 1.$@2</result>
-+                </rule>
-+                <rule>
-+                  <pattern>org.objectweb.asm.*</pattern>
-+                  <result>com.google.inject.internal.asm.$@1</result>
-+                </rule>
-+                <rule>
-+                  <pattern>org.objectweb.asm.**.*</pattern>
-+                  <result>com.google.inject.internal.asm. at 1.$@2</result>
-+                </rule>
-+                <keep>
-+                  <pattern>com.google.inject.**</pattern>
-+                </keep>
-+                <keep>
-+                  <pattern>com.googlecode.**</pattern>
-+                </keep>
-+              </rules>
-             </configuration>
--          </plugin>
--          <plugin>
-             <!--
--             | Package the original non-JarJar'd classes so extensions can compile against them
-+             | JarJar all classes before running tests
-             -->
-+            <executions>
-+              <execution>
-+                <id>jarjar-classes</id>
-+                <phase>process-test-classes</phase>
-+                <goals>
-+                  <goal>jarjar</goal>
-+                </goals>
-+                <configuration>
-+                  <input>{classes}</input>
-+                </configuration>
-+              </execution>
-+              <execution>
-+                <id>jarjar-test-classes</id>
-+                <phase>process-test-classes</phase>
-+                <goals>
-+                  <goal>jarjar</goal>
-+                </goals>
-+                <configuration>
-+                  <input>{test-classes}</input>
-+                </configuration>
-+              </execution>
-+            </executions>
-+          </plugin>
-+          <!--
-+           | Attach original (non-JarJar'd) classes
-+          -->
-+          <plugin>
-             <artifactId>maven-jar-plugin</artifactId>
-             <executions>
-               <execution>
--                <id>no_deps</id>
-+                <id>classes</id>
-                 <phase>package</phase>
-                 <goals>
-                   <goal>jar</goal>
-                 </goals>
-                 <configuration>
-                   <classesDirectory>${project.build.directory}/original-classes</classesDirectory>
--                  <classifier>no_deps</classifier>
-+                  <classifier>classes</classifier>
-+                  <archive>
-+                    <manifestFile combine.self="override" />
-+                  </archive>
-                 </configuration>
-               </execution>
-             </executions>
-@@ -269,6 +299,43 @@
-         </plugins>
-       </build>
-     </profile>
-+    <profile>
-+      <!--
-+       | m2e profile - enable use of JarJar inside Eclipse
-+      -->
-+      <id>m2e</id>
-+      <activation>
-+        <property>
-+          <name>m2e.version</name>
-+        </property>
-+      </activation>
-+      <build>
-+        <pluginManagement>
-+          <plugins>
-+            <plugin>
-+              <groupId>org.eclipse.m2e</groupId>
-+              <artifactId>lifecycle-mapping</artifactId>
-+              <version>1.0.0</version>
-+              <configuration>
-+                <lifecycleMappingMetadata>
-+                  <pluginExecutions>
-+                    <pluginExecution>
-+                      <pluginExecutionFilter>
-+                        <groupId>org.sonatype.plugins</groupId>
-+                        <artifactId>jarjar-maven-plugin</artifactId>
-+                        <versionRange>[1.4,)</versionRange>
-+                        <goals><goal>jarjar</goal></goals>
-+                      </pluginExecutionFilter>
-+                      <action><execute /></action>
-+                    </pluginExecution>
-+                  </pluginExecutions>
-+                </lifecycleMappingMetadata>
-+              </configuration>
-+            </plugin>
-+          </plugins>
-+        </pluginManagement>
-+      </build>
-+    </profile>
-   </profiles>
- 
- </project>
-diff --git a/core/test/com/googlecode/guice/OSGiContainerTest.java b/core/test/com/googlecode/guice/OSGiContainerTest.java
-index 77ab8fa..6cb2b1b 100644
---- a/core/test/com/googlecode/guice/OSGiContainerTest.java
-+++ b/core/test/com/googlecode/guice/OSGiContainerTest.java
-@@ -58,6 +58,7 @@ public class OSGiContainerTest
-   static final String AOPALLIANCE_JAR = System.getProperty("aopalliance.jar", "lib/aopalliance.jar");
- /*end[AOP]*/
-   static final String JAVAX_INJECT_JAR = System.getProperty("javax.inject.jar", "lib/javax.inject.jar");
-+  static final String GUAVA_JAR = System.getProperty("guava.jar", "lib/guava-11.0.2.jar");
- 
-   // dynamically build test bundles
-   @Override protected void setUp()
-@@ -71,6 +72,7 @@ public class OSGiContainerTest
-     assertTrue(failMsg(), new File(AOPALLIANCE_JAR).isFile());
- /*end[AOP]*/
-     assertTrue(failMsg(), new File(JAVAX_INJECT_JAR).isFile());
-+    assertTrue(failMsg(), new File(GUAVA_JAR).isFile());
- 
-     Properties instructions = new Properties();
- 
-@@ -86,6 +88,12 @@ public class OSGiContainerTest
-     buildBundle("javax.inject", instructions, JAVAX_INJECT_JAR);
-     instructions.clear();
- 
-+    // early versions of guava did not ship with OSGi metadata
-+    instructions.setProperty("Export-Package", "com.google.common.*");
-+    instructions.setProperty("Import-Package", "*;resolution:=optional");
-+    buildBundle("guava", instructions, GUAVA_JAR);
-+    instructions.clear();
-+
-     // strict imports to make sure test bundle only has access to these packages
-     instructions.setProperty("Import-Package", "org.osgi.framework,"
- /*if[AOP]*/
-@@ -144,6 +152,7 @@ public class OSGiContainerTest
-       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/aopalliance.jar");
- /*end[AOP]*/
-       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/javax.inject.jar");
-+      systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/guava.jar");
-       systemContext.installBundle("reference:file:" + GUICE_JAR);
-       systemContext.installBundle("reference:file:" + BUILD_TEST_DIR + "/osgitests.jar").start();
- 
-diff --git a/extensions/assistedinject/build.xml b/extensions/assistedinject/build.xml
-index 16557de..459ff9e 100644
---- a/extensions/assistedinject/build.xml
-+++ b/extensions/assistedinject/build.xml
-@@ -10,11 +10,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/grapher/build.xml b/extensions/grapher/build.xml
-index d36fdcd..d5524dd 100644
---- a/extensions/grapher/build.xml
-+++ b/extensions/grapher/build.xml
-@@ -10,11 +10,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/jmx/build.xml b/extensions/jmx/build.xml
-index 1bdcb97..8a99b77 100644
---- a/extensions/jmx/build.xml
-+++ b/extensions/jmx/build.xml
-@@ -10,11 +10,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/jndi/build.xml b/extensions/jndi/build.xml
-index 14eaa8b..5c366a2 100644
---- a/extensions/jndi/build.xml
-+++ b/extensions/jndi/build.xml
-@@ -10,11 +10,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/multibindings/build.xml b/extensions/multibindings/build.xml
-index 7a23462..2f72159 100644
---- a/extensions/multibindings/build.xml
-+++ b/extensions/multibindings/build.xml
-@@ -10,11 +10,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/persist/build.xml b/extensions/persist/build.xml
-index 9be40c8..764c726 100644
---- a/extensions/persist/build.xml
-+++ b/extensions/persist/build.xml
-@@ -11,11 +11,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/pom.xml b/extensions/pom.xml
-index bd706c7..c1fb034 100644
---- a/extensions/pom.xml
-+++ b/extensions/pom.xml
-@@ -43,6 +43,7 @@
-       <groupId>com.google.inject</groupId>
-       <artifactId>guice</artifactId>
-       <version>${project.version}</version>
-+      <scope>provided</scope>
-     </dependency>
-     <!--
-      | Some extension tests depend on the core tests
-@@ -101,41 +102,22 @@
-   <profiles>
-     <profile>
-       <!--
--       | JarJar build profile: re-package ASM and CGLIB references under the Guice namespace
-+       | If JarJar build profile is disabled we need CGLIB during tests
-       -->
--      <id>guice.with.jarjar</id>
-       <activation>
-         <property>
-           <name>guice.with.jarjar</name>
--          <value>!false</value>
-+          <value>false</value>
-         </property>
-       </activation>
-       <dependencies>
--        <!--
--         | Extensions compile first against the non-JarJar'd core - and are then JarJar'd themselves
--         | (optional dependency so it doesn't leak to client projects that depend on Guice artifacts)
--        -->
-         <dependency>
--          <groupId>com.google.inject</groupId>
--          <artifactId>guice</artifactId>
--          <version>${project.version}</version>
--          <classifier>no_deps</classifier>
--          <optional>true</optional>
-+          <groupId>cglib</groupId>
-+          <artifactId>cglib</artifactId>
-+          <version>3.1</version>
-+          <scope>test</scope>
-         </dependency>
-       </dependencies>
--      <build>
--        <plugins>
--          <plugin>
--            <groupId>org.sonatype.plugins</groupId>
--            <artifactId>jarjar-maven-plugin</artifactId>
--            <configuration>
--              <excludes>
--                <exclude>*:*</exclude>
--              </excludes>
--            </configuration>
--          </plugin>
--        </plugins>
--      </build>
-     </profile>
-   </profiles>
- 
-diff --git a/extensions/servlet/build.xml b/extensions/servlet/build.xml
-index d7a10e1..5bee7e5 100644
---- a/extensions/servlet/build.xml
-+++ b/extensions/servlet/build.xml
-@@ -12,11 +12,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/spring/build.xml b/extensions/spring/build.xml
-index 16c8299..3051929 100644
---- a/extensions/spring/build.xml
-+++ b/extensions/spring/build.xml
-@@ -10,11 +10,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/struts2/build.xml b/extensions/struts2/build.xml
-index 820dfa2..6463274 100644
---- a/extensions/struts2/build.xml
-+++ b/extensions/struts2/build.xml
-@@ -11,11 +11,10 @@
-     <fileset dir="../servlet/build" includes="*.jar"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/extensions/throwingproviders/build.xml b/extensions/throwingproviders/build.xml
-index 9d36431..27c20e0 100644
---- a/extensions/throwingproviders/build.xml
-+++ b/extensions/throwingproviders/build.xml
-@@ -10,11 +10,10 @@
-     <pathelement path="../../build/classes"/>
-   </path>
- 
--  <target name="jar" depends="jar.withrenameddeps, manifest" description="Build jar.">
-+  <target name="jar" depends="compile, manifest" description="Build jar.">
-     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
-         manifest="${build.dir}/META-INF/MANIFEST.MF">
--      <zipfileset src="${build.dir}/${ant.project.name}-with-deps.jar"
--          excludes="com/google/inject/internal/**"/>
-+      <fileset dir="${build.dir}/classes"/>
-     </jar>
-   </target>
- 
-diff --git a/guice.iml b/guice.iml
-index 53b2d05..8dd0ae2 100644
---- a/guice.iml
-+++ b/guice.iml
-@@ -87,6 +87,15 @@
-         <SOURCES />
-       </library>
-     </orderEntry>
-+    <orderEntry type="module-library" exported="">
-+      <library>
-+        <CLASSES>
-+          <root url="jar://$MODULE_DIR$/lib/guava-11.0.2.jar!/" />
-+        </CLASSES>
-+        <JAVADOC />
-+        <SOURCES />
-+      </library>
-+    </orderEntry>
-   </component>
- </module>
- 
-diff --git a/lib/build/guava-11.0.1.jar b/lib/build/guava-11.0.1.jar
-deleted file mode 100644
-index af4a383..0000000
-Binary files a/lib/build/guava-11.0.1.jar and /dev/null differ
-diff --git a/lib/guava-11.0.2.jar b/lib/guava-11.0.2.jar
-new file mode 100644
-index 0000000..c8c8d5d
-Binary files /dev/null and b/lib/guava-11.0.2.jar differ
-diff --git a/pom.xml b/pom.xml
-index 0805839..21ea053 100644
---- a/pom.xml
-+++ b/pom.xml
-@@ -196,78 +196,6 @@ See the Apache License Version 2.0 for the specific language governing permissio
-             </execution>
-           </executions>
-         </plugin>
--        <!--
--         | Shared JarJar configuration
--        -->
--        <plugin>
--          <groupId>org.sonatype.plugins</groupId>
--          <artifactId>jarjar-maven-plugin</artifactId>
--          <version>1.4</version>
--          <configuration>
--            <rules>
--              <rule>
--                <pattern>net.sf.cglib.*</pattern>
--                <result>com.google.inject.internal.cglib.$@1</result>
--              </rule>
--              <rule>
--                <pattern>net.sf.cglib.**.*</pattern>
--                <result>com.google.inject.internal.cglib. at 1.$@2</result>
--              </rule>
--              <rule>
--                <pattern>org.objectweb.asm.*</pattern>
--                <result>com.google.inject.internal.asm.$@1</result>
--              </rule>
--              <rule>
--                <pattern>org.objectweb.asm.**.*</pattern>
--                <result>com.google.inject.internal.asm. at 1.$@2</result>
--              </rule>
--              <rule>
--                <pattern>com.google.common.*</pattern>
--                <result>com.google.inject.internal.guava.$@1</result>
--              </rule>
--              <rule>
--                <pattern>com.google.common.**.*</pattern>
--                <result>com.google.inject.internal.guava. at 1.$@2</result>
--              </rule>
--              <keep>
--                <pattern>com.google.inject.**</pattern>
--              </keep>
--              <keep>
--                <pattern>com.googlecode.**</pattern>
--              </keep>
--              <keep>
--                <!-- the servlet extension uses this but core doesn't,
--                     so we explicitly instruct the build to keep it. -->
--                <pattern>com.google.common.base.Throwables</pattern>
--              </keep>
--            </rules>
--          </configuration>
--          <!--
--           | JarJar all classes before running tests
--          -->
--          <executions>
--            <execution>
--              <id>jarjar-classes</id>
--              <phase>process-test-classes</phase>
--              <goals>
--                <goal>jarjar</goal>
--              </goals>
--              <configuration>
--                <input>{classes}</input>
--              </configuration>
--            </execution>
--            <execution>
--              <id>jarjar-test-classes</id>
--              <phase>process-test-classes</phase>
--              <goals>
--                <goal>jarjar</goal>
--              </goals>
--              <configuration>
--                <input>{test-classes}</input>
--              </configuration>
--            </execution>
--          </executions>
--        </plugin>
-         <plugin>
-           <artifactId>maven-surefire-plugin</artifactId>
-           <version>2.5</version>
-@@ -332,6 +260,10 @@ See the Apache License Version 2.0 for the specific language governing permissio
-                 Ignore-Package,Bnd-LastModified
-               </_removeheaders>
-             </instructions>
-+            <!--
-+             | Exclude from version calculations, as it doesn't use semantic versioning
-+            -->
-+            <excludeDependencies>guava</excludeDependencies>
-           </configuration>
-           <executions>
-             <execution>
diff --git a/PATCHES/GUICE_759_upgrade_to_asm5.patch b/PATCHES/GUICE_759_upgrade_to_asm5.patch
index 37e70b7..6108b35 100644
--- a/PATCHES/GUICE_759_upgrade_to_asm5.patch
+++ b/PATCHES/GUICE_759_upgrade_to_asm5.patch
@@ -1,7 +1,7 @@
 Description: Upgrade ASM to 5.0_BETA (via patched cglib)
 Author: Stuart McCulloch <mcculls at gmail.com>
 Bug-Google: http://code.google.com/p/google-guice/issues/detail?id=759
-Last-Update: 2013-12-10
+Last-Update: 2014-03-10
 
 diff --git a/build.xml b/build.xml
 index d9802ae..ac19447 100644
@@ -47,23 +47,6 @@ index 7606276..5346795 100644
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.1</version>
-diff --git a/extensions/pom.xml b/extensions/pom.xml
-index f50bf3c..150a5d6 100644
---- a/extensions/pom.xml
-+++ b/extensions/pom.xml
-@@ -111,6 +111,12 @@
-       </activation>
-       <dependencies>
-         <dependency>
-+          <groupId>org.ow2.asm</groupId>
-+          <artifactId>asm</artifactId>
-+          <version>5.0_BETA</version>
-+          <scope>test</scope>
-+        </dependency>
-+        <dependency>
-           <groupId>cglib</groupId>
-           <artifactId>cglib</artifactId>
-           <version>3.1</version>
 diff --git a/lib/build/asm-4.2.jar b/lib/build/asm-4.2.jar
 deleted file mode 100644
 index 693913d..0000000
diff --git a/PATCHES/GUICE_799_fix_osgi_metadata.patch b/PATCHES/GUICE_799_fix_osgi_metadata.patch
new file mode 100644
index 0000000..17dbc54
--- /dev/null
+++ b/PATCHES/GUICE_799_fix_osgi_metadata.patch
@@ -0,0 +1,33 @@
+Description: Fix OSGI metadata in latest Maven build
+Author: Stuart McCulloch <mcculls at gmail.com>
+Bug-Google: http://code.google.com/p/google-guice/issues/detail?id=799
+Last-Update: 2014-03-10
+
+diff --git a/pom.xml b/pom.xml
+index dece81f..06ad0f7 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -245,10 +245,8 @@ See the Apache License Version 2.0 for the specific language governing permissio
+               <Bundle-DocURL>http://code.google.com/p/google-guice/</Bundle-DocURL>
+               <Bundle-Name>${project.artifactId}</Bundle-Name>
+               <Bundle-SymbolicName>$(module)</Bundle-SymbolicName>
+-              <Bundle-RequiredExecutionEnvironment>
+-                J2SE-1.5,JavaSE-1.6
+-              </Bundle-RequiredExecutionEnvironment>
+-              <Import-Package>!com.google.inject.*,*</Import-Package>
++              <Bundle-RequiredExecutionEnvironment>JavaSE-1.6</Bundle-RequiredExecutionEnvironment>
++              <Import-Package>!net.sf.cglib.*,!org.objectweb.asm.*,!com.google.inject.*,*</Import-Package>
+               <_exportcontents>!*.internal.*,$(module).*;version=${guice.api.version}</_exportcontents>
+               <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+               <_nouses>true</_nouses>
+@@ -260,6 +258,10 @@ See the Apache License Version 2.0 for the specific language governing permissio
+                 Ignore-Package,Bnd-LastModified
+               </_removeheaders>
+             </instructions>
++            <!--
++             | Exclude from version calculations, as it doesn't use semantic versioning
++            -->
++            <excludeDependencies>guava</excludeDependencies>
+           </configuration>
+           <executions>
+             <execution>
diff --git a/PATCHES/SISUFY.patch b/PATCHES/SISUFY.patch
index d9eaafb..4ed75f2 100644
--- a/PATCHES/SISUFY.patch
+++ b/PATCHES/SISUFY.patch
@@ -1,6 +1,6 @@
 Description: Rename and relabel Google-Guice build to make it clear this is a vendor branch
 Author: Stuart McCulloch <mcculls at gmail.com>
-Last-Update: 2014-01-17
+Last-Update: 2014-03-14
 
 diff --git a/README.md b/README.md
 new file mode 100644
@@ -18,8 +18,21 @@ index 0000000..7597582
 +Because of this dependency difference you should avoid mixing the official Google-Guice library with internal extensions provided by Sisu-Guice and vice-versa. Third-party Guice extensions should be compatible with either library.
 +
 +Sisu-Guice retains the same public API as Google-Guice and is binary compatible from a client perspective.
+diff --git a/common.xml b/common.xml
+index 83d3327..1500850 100644
+--- a/common.xml
++++ b/common.xml
+@@ -35,7 +35,7 @@
+     <property name="Bundle-SymbolicName" value="${module}"/>
+     <property name="Bundle-Version" value="${replace;${version};^[^0-9];0.0.0.$0}"/>
+ 
+-    <property name="Bundle-Description" value="Guice is a lightweight dependency injection framework for Java 5 and above"/>
++    <property name="Bundle-Description" value="Guice is a lightweight dependency injection framework for Java 6 and above"/>
+     <property name="Bundle-DocURL" value="http://code.google.com/p/google-guice/"/>
+     <property name="Bundle-Copyright" value="Copyright (C) 2006 Google Inc."/>
+     <property name="Bundle-License" value="http://www.apache.org/licenses/LICENSE-2.0.txt"/>
 diff --git a/core/pom.xml b/core/pom.xml
-index 97c8e60..27f5ea5 100644
+index ea2212a..92a9d88 100644
 --- a/core/pom.xml
 +++ b/core/pom.xml
 @@ -4,14 +4,15 @@
@@ -39,9 +52,26 @@ index 97c8e60..27f5ea5 100644
 -  <name>Google Guice - Core Library</name>
 +  <name>Sisu Guice - Core Library</name>
  
-   <properties>
-     <cglib.version>3.0</cglib.version>
-@@ -123,18 +124,6 @@
+   <dependencies>
+     <dependency>
+@@ -50,6 +51,7 @@
+       <artifactId>cglib</artifactId>
+       <version>3.1</version>
+       <optional>true</optional>
++      <scope>provided</scope>
+     </dependency>
+     <dependency>
+       <groupId>javax.inject</groupId>
+@@ -86,7 +88,7 @@
+         <artifactId>maven-remote-resources-plugin</artifactId>
+       </plugin>
+       <!--
+-       | Enable Java5 conformance checks
++       | Enable Java6 conformance checks
+       -->
+       <plugin>
+         <groupId>org.codehaus.mojo</groupId>
+@@ -139,18 +141,6 @@
            </excludes>
          </configuration>
        </plugin>
@@ -113,10 +143,10 @@ index 6f63452..920f7ba 100644
        <version>${project.version}</version>
      </dependency>
 diff --git a/extensions/jmx/pom.xml b/extensions/jmx/pom.xml
-index 62c7d17..b6d53bf 100644
+index f3298e7..7de6431 100644
 --- a/extensions/jmx/pom.xml
 +++ b/extensions/jmx/pom.xml
-@@ -4,13 +4,13 @@
+@@ -4,14 +4,14 @@
    <modelVersion>4.0.0</modelVersion>
  
    <parent>
@@ -131,7 +161,8 @@ index 62c7d17..b6d53bf 100644
 -  <name>Google Guice - Extensions - JMX</name>
 +  <name>Sisu Guice - Extensions - JMX</name>
  
- </project>
+   <build>
+     <plugins>
 diff --git a/extensions/jndi/pom.xml b/extensions/jndi/pom.xml
 index fb9bc3c..f78153a 100644
 --- a/extensions/jndi/pom.xml
@@ -201,7 +232,7 @@ index 8875e39..9eb7ee9 100644
  
  </project>
 diff --git a/extensions/persist/pom.xml b/extensions/persist/pom.xml
-index 18b15a3..2edfc04 100644
+index 89bcc06..a5d63aa 100644
 --- a/extensions/persist/pom.xml
 +++ b/extensions/persist/pom.xml
 @@ -4,14 +4,14 @@
@@ -222,7 +253,7 @@ index 18b15a3..2edfc04 100644
    <dependencies>
      <dependency>
 diff --git a/extensions/pom.xml b/extensions/pom.xml
-index bd706c7..5b6574b 100644
+index b758bcd..009c439 100644
 --- a/extensions/pom.xml
 +++ b/extensions/pom.xml
 @@ -4,17 +4,16 @@
@@ -245,7 +276,7 @@ index bd706c7..5b6574b 100644
  
    <modules>
      <module>assistedinject</module>
-@@ -40,17 +39,17 @@
+@@ -40,16 +39,17 @@
       | All extensions depend on the core
      -->
      <dependency>
@@ -254,7 +285,7 @@ index bd706c7..5b6574b 100644
 +      <groupId>org.sonatype.sisu</groupId>
 +      <artifactId>sisu-guice</artifactId>
        <version>${project.version}</version>
-       <scope>provided</scope>
++      <scope>provided</scope>
      </dependency>
      <!--
       | Some extension tests depend on the core tests
@@ -267,7 +298,16 @@ index bd706c7..5b6574b 100644
        <version>${project.version}</version>
        <classifier>tests</classifier>
        <scope>test</scope>
-@@ -79,22 +78,10 @@
+@@ -75,7 +75,7 @@
+         <artifactId>maven-remote-resources-plugin</artifactId>
+       </plugin>
+       <!--
+-       | Enable Java5 conformance checks
++       | Enable Java6 conformance checks
+       -->
+       <plugin>
+         <groupId>org.codehaus.mojo</groupId>
+@@ -89,22 +89,10 @@
          <artifactId>maven-bundle-plugin</artifactId>
          <configuration>
            <instructions>
@@ -290,7 +330,7 @@ index bd706c7..5b6574b 100644
 -      </plugin>
      </plugins>
    </build>
- 
+ </project>
 diff --git a/extensions/service/pom.xml b/extensions/service/pom.xml
 index 8dd4001..9eede3e 100644
 --- a/extensions/service/pom.xml
@@ -381,10 +421,10 @@ index cf987cf..2a60ebd 100644
        <version>${project.version}</version>
      </dependency>
 diff --git a/extensions/throwingproviders/pom.xml b/extensions/throwingproviders/pom.xml
-index cd866cc..d086054 100644
+index 63a8b78..bb24528 100644
 --- a/extensions/throwingproviders/pom.xml
 +++ b/extensions/throwingproviders/pom.xml
-@@ -4,13 +4,13 @@
+@@ -4,14 +4,14 @@
    <modelVersion>4.0.0</modelVersion>
  
    <parent>
@@ -399,9 +439,10 @@ index cd866cc..d086054 100644
 -  <name>Google Guice - Extensions - ThrowingProviders</name>
 +  <name>Sisu Guice - Extensions - ThrowingProviders</name>
  
- </project>
+   <build>
+     <plugins>
 diff --git a/pom.xml b/pom.xml
-index 0805839..83477bc 100644
+index 098a9cb..981580c 100644
 --- a/pom.xml
 +++ b/pom.xml
 @@ -18,21 +18,21 @@ See the Apache License Version 2.0 for the specific language governing permissio
@@ -428,7 +469,7 @@ index 0805839..83477bc 100644
  
    <description>
 -    Guice is a lightweight dependency injection framework for Java 5 and above
-+    Patched build of Guice: a lightweight dependency injection framework for Java 5 and above
++    Patched build of Guice: a lightweight dependency injection framework for Java 6 and above
    </description>
  
    <url>http://code.google.com/p/google-guice/</url>
@@ -462,19 +503,29 @@ index 0805839..83477bc 100644
    </properties>
  
    <dependencies>
-@@ -316,7 +315,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
+@@ -165,7 +164,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
+           </executions>
+         </plugin>
+         <!--
+-         | Make sure we only use Java5 methods
++         | Make sure we only use Java6 methods
+         -->
+         <plugin>
+           <artifactId>maven-compiler-plugin</artifactId>
+@@ -244,7 +243,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
                <Bundle-Copyright>Copyright (C) 2006 Google Inc.</Bundle-Copyright>
                <Bundle-DocURL>http://code.google.com/p/google-guice/</Bundle-DocURL>
                <Bundle-Name>${project.artifactId}</Bundle-Name>
 -              <Bundle-SymbolicName>$(module)</Bundle-SymbolicName>
 +              <Bundle-Vendor>Sonatype, Inc.</Bundle-Vendor>
-               <Bundle-RequiredExecutionEnvironment>
-                 J2SE-1.5,JavaSE-1.6
-               </Bundle-RequiredExecutionEnvironment>
-@@ -367,82 +366,56 @@ See the Apache License Version 2.0 for the specific language governing permissio
+               <Bundle-RequiredExecutionEnvironment>JavaSE-1.6</Bundle-RequiredExecutionEnvironment>
+               <Import-Package>!net.sf.cglib.*,!org.objectweb.asm.*,!com.google.inject.*,*</Import-Package>
+               <_exportcontents>!*.internal.*,$(module).*;version=${guice.api.version}</_exportcontents>
+@@ -296,83 +295,67 @@ See the Apache License Version 2.0 for the specific language governing permissio
+         </plugin>
          <plugin>
            <artifactId>maven-javadoc-plugin</artifactId>
-           <version>2.7</version>
+-          <version>2.7</version>
 -          <executions>
 -            <execution>
 -              <phase>package</phase>
@@ -483,6 +534,7 @@ index 0805839..83477bc 100644
 -              </goals>
 -            </execution>
 -          </executions>
++          <version>2.9.1</version>
 +          <configuration>
 +            <doclet>com.google.doclava.Doclava</doclet>
 +            <docletPath>
@@ -490,9 +542,19 @@ index 0805839..83477bc 100644
 +              ${project.basedir}/../../lib/build/doclava.jar
 +            </docletPath>
 +            <!--
-+             | bootclasspath required by Sun's JVM 
++             | bootclasspath required by Sun's JVM
 +            -->
 +            <bootclasspath>${sun.boot.class.path}</bootclasspath>
++            <!--
++             | javadoc requires @javax.annotation.Nullable
++            -->
++            <additionalDependencies>
++              <additionalDependency>
++                <groupId>com.google.code.findbugs</groupId>
++                <artifactId>jsr305</artifactId>
++                <version>2.0.3</version>
++              </additionalDependency>
++            </additionalDependencies>
 +            <excludePackageNames>*.internal</excludePackageNames>
 +            <additionalparam>
 +              -quiet
@@ -532,7 +594,7 @@ index 0805839..83477bc 100644
          <plugin>
            <artifactId>maven-release-plugin</artifactId>
 -          <version>2.1</version>
-+          <version>2.2.1</version>
++          <version>2.5</version>
            <configuration>
              <autoVersionSubmodules>true</autoVersionSubmodules>
            </configuration>
diff --git a/build.xml b/build.xml
index ac19447..e3fdc51 100644
--- a/build.xml
+++ b/build.xml
@@ -104,7 +104,7 @@
         <pathelement location="${build.dir}/dist/guice-${version}.jar"/>
         <pathelement location="lib/javax.inject.jar"/>
         <pathelement location="lib/aopalliance.jar"/>
-        <pathelement location="lib/guava-11.0.2.jar"/>
+        <pathelement location="lib/guava-16.0.1.jar"/>
         <pathelement location="lib/build/junit.jar"/>
         <pathelement location="lib/build/servlet-api-2.5.jar"/>
         <pathelement location="lib/build/easymock.jar"/>
@@ -135,7 +135,7 @@
     <javadoc packagenames="com.google.*"
                  docletpath="${jdiff.home}/jdiff.jar${path.separator}${jdiff.home}/xerces.jar"
              maxmemory="512M"
-             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}guava-11.0.2.jar">
+             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}lib/guava-16.0.1.jar">
       <fileset dir="${src.dir}" defaultexcludes="yes">
         <include name="com/google/**"/>
         <exclude name="com/google/inject/internal/**"/>
@@ -164,7 +164,7 @@
                      docletpath="${jdiff.home}/jdiff.jar${path.separator}${jdiff.home}/xerces.jar"
                  maxmemory="512M"
                      sourcefiles="${jdiff.home}/Null.java"
-                 classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}guava-11.0.2.jar">
+                 classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}lib/guava-16.0.1.jar">
           <doclet name="jdiff.JDiff">
                 <param name="-oldapi" value="${old.api}"/>
                 <param name="-oldapidir" value="latest-api-diffs"/>             
@@ -184,7 +184,7 @@
              docletpath="lib/build/doclava.jar"
              bootclasspath="${java.home}/lib/rt.jar"
              maxmemory="512M"
-             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}guava-11.0.2.jar">
+             classpath="lib/javax.inject.jar${path.separator}lib/aopalliance.jar${path.separator}lib/guava-16.0.1.jar">
       <fileset dir="${src.dir}" defaultexcludes="yes">
         <include name="com/google/**"/>
         <exclude name="com/google/inject/internal/**"/>
diff --git a/common.xml b/common.xml
index 73ac4c3..1500850 100644
--- a/common.xml
+++ b/common.xml
@@ -14,7 +14,7 @@
     <javac srcdir="${src.dir}"
          debug="on"
          destdir="${build.dir}/classes"
-         source="1.5" target="1.5" includeantruntime="false">
+         source="1.6" target="1.6" includeantruntime="false">
       <compilerarg value="-Xlint:all,-serial"/>
       <classpath refid="compile.classpath"/>
     </javac>
@@ -35,11 +35,11 @@
     <property name="Bundle-SymbolicName" value="${module}"/>
     <property name="Bundle-Version" value="${replace;${version};^[^0-9];0.0.0.$0}"/>
 
-    <property name="Bundle-Description" value="Guice is a lightweight dependency injection framework for Java 5 and above"/>
+    <property name="Bundle-Description" value="Guice is a lightweight dependency injection framework for Java 6 and above"/>
     <property name="Bundle-DocURL" value="http://code.google.com/p/google-guice/"/>
     <property name="Bundle-Copyright" value="Copyright (C) 2006 Google Inc."/>
     <property name="Bundle-License" value="http://www.apache.org/licenses/LICENSE-2.0.txt"/>
-    <property name="Bundle-RequiredExecutionEnvironment" value="J2SE-1.5,JavaSE-1.6"/>
+    <property name="Bundle-RequiredExecutionEnvironment" value="JavaSE-1.6"/>
     <property name="Bundle-Vendor" value="Google, Inc."/>
 
     <property name="Export-Package" value="!${module}.internal.*,${module}.*;version=${api.version}"/>
@@ -80,7 +80,7 @@
     <javac srcdir="${test.dir}"
          debug="on"
          destdir="${build.dir}/test"
-         source="1.5" target="1.5" includeantruntime="false">
+         source="1.6" target="1.6" includeantruntime="false">
       <classpath path="${build.dir}/classes"/>
       <classpath path="${build.dir}/test"/>
       <classpath refid="compile.classpath"/>
diff --git a/core/pom.xml b/core/pom.xml
index fbc38b9..2f48c25 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>guice-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <groupId>org.sonatype.sisu</groupId>
@@ -34,7 +34,7 @@
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
-      <version>11.0.2</version>
+      <version>16.0.1</version>
     </dependency>
     <!--
      | CGLIB is embedded by default by the JarJar build profile
@@ -88,7 +88,7 @@
         <artifactId>maven-remote-resources-plugin</artifactId>
       </plugin>
       <!--
-       | Enable Java5 conformance checks
+       | Enable Java6 conformance checks
       -->
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
@@ -107,6 +107,8 @@
            | Temporarily excluded tests
           -->
           <excludes>
+            <exclude>**/*$*</exclude>
+            <exclude>**/ErrorHandlingTest*</exclude>
             <exclude>**/OSGiContainerTest*</exclude>
             <exclude>**/ScopesTest*</exclude>
             <exclude>**/TypeConversionTest*</exclude>
@@ -211,7 +213,7 @@
     </profile>
     <profile>
       <!--
-       | JarJar build profile: embed CGLIB (and ASM) classes under Guice namespace
+       | JarJar build profile: Embed CGLIB (and ASM) classes under a Guice namespace
       -->
       <id>guice.with.jarjar</id>
       <activation>
@@ -226,6 +228,12 @@
             <groupId>org.sonatype.plugins</groupId>
             <artifactId>jarjar-maven-plugin</artifactId>
             <version>1.8</version>
+            <executions>
+              <execution>
+                <id>jarjar</id>
+                <goals><goal>jarjar</goal></goals>
+              </execution>
+            </executions>
             <configuration>
               <overwrite>true</overwrite>
               <includes>
@@ -257,36 +265,11 @@
                 </keep>
               </rules>
             </configuration>
-            <!--
-             | JarJar all classes before running tests
-            -->
-            <executions>
-              <execution>
-                <id>jarjar-classes</id>
-                <phase>process-test-classes</phase>
-                <goals>
-                  <goal>jarjar</goal>
-                </goals>
-                <configuration>
-                  <input>{classes}</input>
-                </configuration>
-              </execution>
-              <execution>
-                <id>jarjar-test-classes</id>
-                <phase>process-test-classes</phase>
-                <goals>
-                  <goal>jarjar</goal>
-                </goals>
-                <configuration>
-                  <input>{test-classes}</input>
-                </configuration>
-              </execution>
-            </executions>
           </plugin>
-          <!--
-           | Attach original (non-JarJar'd) classes
-          -->
           <plugin>
+            <!--
+             | Package the original non-JarJar'd classes so extensions can compile against them
+            -->
             <artifactId>maven-jar-plugin</artifactId>
             <executions>
               <execution>
@@ -346,5 +329,4 @@
       </build>
     </profile>
   </profiles>
-
 </project>
diff --git a/core/src/com/google/inject/Inject.java b/core/src/com/google/inject/Inject.java
index e3bbd27..535c0a4 100644
--- a/core/src/com/google/inject/Inject.java
+++ b/core/src/com/google/inject/Inject.java
@@ -38,7 +38,7 @@ import java.lang.annotation.Target;
  * 
  * <li>Pre-constructed instances passed to {@link Injector#injectMembers},
  * {@link com.google.inject.binder.LinkedBindingBuilder#toInstance(Object)} and
- * {@link com.google.inject.binder.LinkedBindingBuilder#toProvider(Provider)}.
+ * {@link com.google.inject.binder.LinkedBindingBuilder#toProvider(javax.inject.Provider)}.
  * In this case all constructors are, of course, ignored.
  *
  * <li>Static fields and methods of classes which any {@link Module} has
diff --git a/core/src/com/google/inject/binder/LinkedBindingBuilder.java b/core/src/com/google/inject/binder/LinkedBindingBuilder.java
index 08ca1ef..5ba8b67 100644
--- a/core/src/com/google/inject/binder/LinkedBindingBuilder.java
+++ b/core/src/com/google/inject/binder/LinkedBindingBuilder.java
@@ -57,6 +57,13 @@ public interface LinkedBindingBuilder<T> extends ScopedBindingBuilder {
    * @see com.google.inject.Injector#injectMembers
    */
   ScopedBindingBuilder toProvider(Provider<? extends T> provider);
+  
+  /**
+   * See the EDSL examples at {@link com.google.inject.Binder}.
+   *
+   * @see com.google.inject.Injector#injectMembers
+   */
+  ScopedBindingBuilder toProvider(javax.inject.Provider<? extends T> provider);
 
   /**
    * See the EDSL examples at {@link com.google.inject.Binder}.
diff --git a/core/src/com/google/inject/internal/BindingBuilder.java b/core/src/com/google/inject/internal/BindingBuilder.java
index a6260f3..dfedea4 100644
--- a/core/src/com/google/inject/internal/BindingBuilder.java
+++ b/core/src/com/google/inject/internal/BindingBuilder.java
@@ -97,6 +97,10 @@ public class BindingBuilder<T> extends AbstractBindingBuilder<T>
   }
 
   public BindingBuilder<T> toProvider(Provider<? extends T> provider) {
+    return toProvider((javax.inject.Provider<T>) provider);
+  }
+
+  public BindingBuilder<T> toProvider(javax.inject.Provider<? extends T> provider) {
     checkNotNull(provider, "provider");
     checkNotTargetted();
 
diff --git a/core/src/com/google/inject/internal/BindingProcessor.java b/core/src/com/google/inject/internal/BindingProcessor.java
index 7ce3ea0..8e83d18 100644
--- a/core/src/com/google/inject/internal/BindingProcessor.java
+++ b/core/src/com/google/inject/internal/BindingProcessor.java
@@ -53,7 +53,8 @@ final class BindingProcessor extends AbstractBindingProcessor {
     Class<?> rawType = command.getKey().getTypeLiteral().getRawType();
     if (Void.class.equals(rawType)) {
       if (command instanceof ProviderInstanceBinding
-          && ((ProviderInstanceBinding) command).getProviderInstance() instanceof ProviderMethod) {
+          && ((ProviderInstanceBinding) command).getUserSuppliedProvider()
+              instanceof ProviderMethod) {
         errors.voidProviderMethod();
       } else {
         errors.missingConstantValues();
@@ -102,10 +103,11 @@ final class BindingProcessor extends AbstractBindingProcessor {
       @Override
       public Boolean visit(ProviderInstanceBinding<? extends T> binding) {
         prepareBinding();
-        Provider<? extends T> provider = binding.getProviderInstance();
+        javax.inject.Provider<? extends T> provider = binding.getUserSuppliedProvider();
         Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
-        Initializable<Provider<? extends T>> initializable = initializer
-            .<Provider<? extends T>>requestInjection(injector, provider, null, source, injectionPoints);
+        Initializable<? extends javax.inject.Provider<? extends T>> initializable =
+            initializer.<javax.inject.Provider<? extends T>>requestInjection(
+                injector, provider, null, source, injectionPoints);
         // always visited with Binding<T>
         @SuppressWarnings("unchecked") 
         InternalFactory<T> factory = new InternalFactoryToInitializableAdapter<T>(
@@ -126,7 +128,7 @@ final class BindingProcessor extends AbstractBindingProcessor {
         @SuppressWarnings("unchecked") 
         BoundProviderFactory<T> boundProviderFactory = new BoundProviderFactory<T>(
             injector, providerKey, source, !injector.options.disableCircularProxies,
-            injector.provisionListenerStore.get((ProviderKeyBinding<T>)binding));
+            injector.provisionListenerStore.get((ProviderKeyBinding<T>) binding));
         bindingData.addCreationListener(boundProviderFactory);
         InternalFactory<? extends T> scopedFactory = Scoping.scope(
             key, injector, (InternalFactory<? extends T>) boundProviderFactory, source, scoping);
diff --git a/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java b/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java
index 03417e6..b534f89 100644
--- a/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java
+++ b/core/src/com/google/inject/internal/InternalFactoryToInitializableAdapter.java
@@ -18,7 +18,6 @@ package com.google.inject.internal;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.inject.Provider;
 import com.google.inject.spi.Dependency;
 import com.google.inject.spi.ProviderInstanceBinding;
 
@@ -31,10 +30,10 @@ import com.google.inject.spi.ProviderInstanceBinding;
 final class InternalFactoryToInitializableAdapter<T> extends ProviderInternalFactory<T> {
 
   private final ProvisionListenerStackCallback<T> provisionCallback;
-  private final Initializable<Provider<? extends T>> initializable;
+  private final Initializable<? extends javax.inject.Provider<? extends T>> initializable;
 
   public InternalFactoryToInitializableAdapter(
-      Initializable<Provider<? extends T>> initializable,
+      Initializable<? extends javax.inject.Provider<? extends T>> initializable,
       Object source, boolean allowProxy,
       ProvisionListenerStackCallback<T> provisionCallback) {
     super(source, allowProxy);
diff --git a/core/src/com/google/inject/internal/InternalFlags.java b/core/src/com/google/inject/internal/InternalFlags.java
index 31d412d..41c9799 100644
--- a/core/src/com/google/inject/internal/InternalFlags.java
+++ b/core/src/com/google/inject/internal/InternalFlags.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.inject.internal;
 
 import java.util.Arrays;
diff --git a/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java b/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
index 971a1d0..ab05b6d 100644
--- a/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
+++ b/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
@@ -30,18 +30,19 @@ import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.ProviderInstanceBinding;
 import com.google.inject.spi.ProviderWithExtensionVisitor;
+import com.google.inject.util.Providers;
 
 import java.util.Set;
 
 final class ProviderInstanceBindingImpl<T> extends BindingImpl<T>
     implements ProviderInstanceBinding<T> {
 
-  final Provider<? extends T> providerInstance;
+  final javax.inject.Provider<? extends T> providerInstance;
   final ImmutableSet<InjectionPoint> injectionPoints;
 
   public ProviderInstanceBindingImpl(InjectorImpl injector, Key<T> key,
       Object source, InternalFactory<? extends T> internalFactory, Scoping scoping,
-      Provider<? extends T> providerInstance,
+      javax.inject.Provider<? extends T> providerInstance,
       Set<InjectionPoint> injectionPoints) {
     super(injector, key, source, internalFactory, scoping);
     this.providerInstance = providerInstance;
@@ -49,7 +50,7 @@ final class ProviderInstanceBindingImpl<T> extends BindingImpl<T>
   }
 
   public ProviderInstanceBindingImpl(Object source, Key<T> key, Scoping scoping,
-      Set<InjectionPoint> injectionPoints, Provider<? extends T> providerInstance) {
+      Set<InjectionPoint> injectionPoints, javax.inject.Provider<? extends T> providerInstance) {
     super(source, key, scoping);
     this.injectionPoints = ImmutableSet.copyOf(injectionPoints);
     this.providerInstance = providerInstance;
@@ -66,6 +67,10 @@ final class ProviderInstanceBindingImpl<T> extends BindingImpl<T>
   }
 
   public Provider<? extends T> getProviderInstance() {
+    return Providers.guicify(providerInstance);
+  }
+  
+  public javax.inject.Provider<? extends T> getUserSuppliedProvider() {
     return providerInstance;
   }
 
@@ -99,7 +104,7 @@ final class ProviderInstanceBindingImpl<T> extends BindingImpl<T>
 
   public void applyTo(Binder binder) {
     getScoping().applyTo(
-        binder.withSource(getSource()).bind(getKey()).toProvider(getProviderInstance()));
+        binder.withSource(getSource()).bind(getKey()).toProvider(getUserSuppliedProvider()));
   }
 
   @Override
diff --git a/core/src/com/google/inject/internal/ProviderMethod.java b/core/src/com/google/inject/internal/ProviderMethod.java
index 6221499..d8bc18b 100644
--- a/core/src/com/google/inject/internal/ProviderMethod.java
+++ b/core/src/com/google/inject/internal/ProviderMethod.java
@@ -24,8 +24,13 @@ import com.google.inject.Key;
 import com.google.inject.PrivateBinder;
 import com.google.inject.Provider;
 import com.google.inject.internal.util.StackTraceElements;
+import com.google.inject.spi.BindingTargetVisitor;
 import com.google.inject.spi.Dependency;
-import com.google.inject.spi.ProviderWithDependencies;
+import com.google.inject.spi.HasDependencies;
+import com.google.inject.spi.ProviderInstanceBinding;
+import com.google.inject.spi.ProviderWithExtensionVisitor;
+import com.google.inject.spi.ProvidesMethodBinding;
+import com.google.inject.spi.ProvidesMethodTargetVisitor;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
@@ -38,7 +43,8 @@ import java.util.Set;
  *
  * @author jessewilson at google.com (Jesse Wilson)
  */
-public class ProviderMethod<T> implements ProviderWithDependencies<T> {
+public class ProviderMethod<T> implements ProviderWithExtensionVisitor<T>, HasDependencies,
+    ProvidesMethodBinding<T> {
   private final Key<T> key;
   private final Class<? extends Annotation> scopeAnnotation;
   private final Object instance;
@@ -76,6 +82,10 @@ public class ProviderMethod<T> implements ProviderWithDependencies<T> {
   public Object getInstance() {
     return instance;
   }
+  
+  public Object getEnclosingInstance() {
+    return instance;
+  }
 
   public void configure(Binder binder) {
     binder = binder.withSource(method);
@@ -114,6 +124,15 @@ public class ProviderMethod<T> implements ProviderWithDependencies<T> {
   public Set<Dependency<?>> getDependencies() {
     return dependencies;
   }
+  
+  @SuppressWarnings("unchecked")
+  public <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
+      ProviderInstanceBinding<? extends B> binding) {
+    if (visitor instanceof ProvidesMethodTargetVisitor) {
+      return ((ProvidesMethodTargetVisitor<T, V>)visitor).visit(this);
+    }
+    return visitor.visit(binding);
+  }
 
   @Override public String toString() {
     return "@Provides " + StackTraceElements.forMember(method).toString();
diff --git a/core/src/com/google/inject/internal/RehashableKeys.java b/core/src/com/google/inject/internal/RehashableKeys.java
index 2fff215..5f9b479 100644
--- a/core/src/com/google/inject/internal/RehashableKeys.java
+++ b/core/src/com/google/inject/internal/RehashableKeys.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.inject.internal;
 
 import com.google.inject.Key;
diff --git a/core/src/com/google/inject/spi/ElementSource.java b/core/src/com/google/inject/spi/ElementSource.java
index 35246d4..e156ba8 100644
--- a/core/src/com/google/inject/spi/ElementSource.java
+++ b/core/src/com/google/inject/spi/ElementSource.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.inject.spi;
 
 import com.google.common.base.Preconditions;
diff --git a/core/src/com/google/inject/spi/ModuleSource.java b/core/src/com/google/inject/spi/ModuleSource.java
index 4e2a549..19add7e 100644
--- a/core/src/com/google/inject/spi/ModuleSource.java
+++ b/core/src/com/google/inject/spi/ModuleSource.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.google.inject.spi;
 
 import com.google.common.base.Preconditions;
diff --git a/core/src/com/google/inject/spi/ProviderInstanceBinding.java b/core/src/com/google/inject/spi/ProviderInstanceBinding.java
index 3698542..ab4aaa4 100644
--- a/core/src/com/google/inject/spi/ProviderInstanceBinding.java
+++ b/core/src/com/google/inject/spi/ProviderInstanceBinding.java
@@ -31,9 +31,16 @@ import java.util.Set;
 public interface ProviderInstanceBinding<T> extends Binding<T>, HasDependencies {
 
   /**
-   * Returns the user-supplied, unscoped provider.
+   * If the user supplied a JSR330 binding, then this will wrap that one. To always return the
+   * user-supplied provider, use {@link #getUserSuppliedProvider}.
+   * 
+   * @deprecated Use {@link #getUserSuppliedProvider} instead.
    */
+  @Deprecated
   Provider<? extends T> getProviderInstance();
+  
+  /** Returns the user-supplied, unscoped provider. */
+  javax.inject.Provider<? extends T> getUserSuppliedProvider();
 
   /**
    * Returns the field and method injection points of the provider, injected at injector-creation
diff --git a/core/src/com/google/inject/spi/ProvidesMethodBinding.java b/core/src/com/google/inject/spi/ProvidesMethodBinding.java
new file mode 100644
index 0000000..0429834
--- /dev/null
+++ b/core/src/com/google/inject/spi/ProvidesMethodBinding.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.spi;
+
+import com.google.inject.Key;
+import com.google.inject.Provides;
+
+import java.lang.reflect.Method;
+
+/**
+ * An {@literal @}{@link Provides} binding.
+ * 
+ * @since 4.0
+ * @author sameb at google.com (Sam Berlin)
+ */
+public interface ProvidesMethodBinding<T> extends HasDependencies {
+  
+  /** Returns the method this binding uses. */
+  Method getMethod(); 
+  
+  /** Returns the instance of the object the method is defined in. */
+  Object getEnclosingInstance();
+  
+  /** Returns the key of the binding. */
+  Key<T> getKey();
+}
diff --git a/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java b/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
new file mode 100644
index 0000000..d42ba95
--- /dev/null
+++ b/core/src/com/google/inject/spi/ProvidesMethodTargetVisitor.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.spi;
+
+import com.google.inject.Provides;
+import com.google.inject.spi.BindingTargetVisitor;
+
+/**
+ * A visitor for the {@literal @}{@link Provides} bindings.
+ * <p>
+ * If your {@link BindingTargetVisitor} implements this interface, bindings created by using
+ * {@code @Provides} will be visited through this interface.
+ *
+ * @since 4.0
+ * @author sameb at google.com (Sam Berlin)
+ */
+public interface ProvidesMethodTargetVisitor<T, V> extends BindingTargetVisitor<T, V> {
+  
+  /**
+   * Visits an {@link ProvidesMethodBinding} created with an {@literal @}{@link Provides} method.
+   */
+  V visit(ProvidesMethodBinding<? extends T> providesMethodBinding);
+}
diff --git a/core/test/com/google/inject/spi/ElementsTest.java b/core/test/com/google/inject/spi/ElementsTest.java
index e2fcff9..778f37e 100644
--- a/core/test/com/google/inject/spi/ElementsTest.java
+++ b/core/test/com/google/inject/spi/ElementsTest.java
@@ -370,11 +370,27 @@ public class ElementsTest extends TestCase {
         return "A";
       }
     };
+    
+    final javax.inject.Provider<Integer> intJavaxProvider = new javax.inject.Provider<Integer>() {
+      public Integer get() {
+        return 42;
+      }
+    };
+    
+    final javax.inject.Provider<Double> doubleJavaxProvider = new javax.inject.Provider<Double>() {
+      @javax.inject.Inject String string;
+      
+      public Double get() {
+        return 42.42;
+      }
+    };
 
     checkModule(
         new AbstractModule() {
           protected void configure() {
             bind(String.class).toProvider(aProvider);
+            bind(Integer.class).toProvider(intJavaxProvider);
+            bind(Double.class).toProvider(doubleJavaxProvider);
             bind(List.class).toProvider(ListProvider.class);
             bind(Collection.class).toProvider(Key.get(ListProvider.class));
             bind(Iterable.class).toProvider(new TypeLiteral<TProvider<List>>() {});
@@ -388,6 +404,7 @@ public class ElementsTest extends TestCase {
             command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
               @Override public Void visit(
                   ProviderInstanceBinding<? extends T> binding) {
+                assertSame(aProvider, binding.getUserSuppliedProvider());
                 assertSame(aProvider, binding.getProviderInstance());
                 return null;
               }
@@ -395,6 +412,47 @@ public class ElementsTest extends TestCase {
             return null;
           }
         },
+        
+        new FailingElementVisitor() {
+          @Override public <T> Void visit(Binding<T> command) {
+            assertTrue(command instanceof ProviderInstanceBinding);
+            assertEquals(Key.get(Integer.class), command.getKey());
+            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
+              @Override public Void visit(
+                  ProviderInstanceBinding<? extends T> binding) {
+                assertSame(intJavaxProvider, binding.getUserSuppliedProvider());
+                assertEquals(42, binding.getProviderInstance().get());
+                // we don't wrap this w/ dependencies if there were none.
+                assertFalse(binding.getProviderInstance() instanceof HasDependencies);
+                return null;
+              }
+            });
+            return null;
+          }
+        },        
+        
+        new FailingElementVisitor() {
+          @Override public <T> Void visit(Binding<T> command) {
+            assertTrue(command instanceof ProviderInstanceBinding);
+            assertEquals(Key.get(Double.class), command.getKey());
+            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
+              @Override public Void visit(
+                  ProviderInstanceBinding<? extends T> binding) {
+                assertSame(doubleJavaxProvider, binding.getUserSuppliedProvider());
+                assertEquals(42.42, binding.getProviderInstance().get());
+                // we do wrap it with dependencies if there were some.
+                assertTrue(binding.getProviderInstance() instanceof HasDependencies);
+                Set<Dependency<?>> deps =
+                    ((HasDependencies) binding.getProviderInstance()).getDependencies();
+                assertEquals(1, deps.size());
+                assertEquals(String.class,
+                    deps.iterator().next().getKey().getTypeLiteral().getRawType());
+                return null;
+              }
+            });
+            return null;
+          }
+        },
 
         new FailingElementVisitor() {
           @Override public <T> Void visit(Binding<T> command) {
diff --git a/core/test/com/google/inject/spi/ProviderMethodsTest.java b/core/test/com/google/inject/spi/ProviderMethodsTest.java
index 8bbb8de..466e835 100644
--- a/core/test/com/google/inject/spi/ProviderMethodsTest.java
+++ b/core/test/com/google/inject/spi/ProviderMethodsTest.java
@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
+import com.google.inject.Binding;
 import com.google.inject.BindingAnnotation;
 import com.google.inject.CreationException;
 import com.google.inject.Guice;
@@ -30,7 +31,6 @@ import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Module;
-import com.google.inject.Provider;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.internal.ProviderMethod;
@@ -354,9 +354,10 @@ public class ProviderMethodsTest extends TestCase implements Module {
         element instanceof ProviderInstanceBinding);
 
     ProviderInstanceBinding binding = (ProviderInstanceBinding) element;
-    Provider provider = binding.getProviderInstance();    
+    javax.inject.Provider provider = binding.getUserSuppliedProvider();    
     assertEquals(ProviderMethod.class, provider.getClass());
-    assertEquals(methodsObject, ((ProviderMethod) provider).getInstance());
+    assertEquals(methodsObject, ((ProviderMethod) provider).getInstance());    
+    assertSame(provider, binding.getProviderInstance());
   }
 
   public void testVoidProviderMethods() {
@@ -403,4 +404,52 @@ public class ProviderMethodsTest extends TestCase implements Module {
       return 42;
     }
   }
-}
\ No newline at end of file
+  
+  public void testSpi() throws Exception {
+    Module m1 = new AbstractModule() {
+      @Override protected void configure() {}
+      @Provides @Named("foo") String provideFoo(Integer dep) { return "foo"; }
+    };
+    Module m2 = new AbstractModule() {
+      @Override protected void configure() {}
+      @Provides Integer provideInt(@Named("foo") String dep) { return 42; }
+    };
+    Injector injector = Guice.createInjector(m1, m2);
+    
+    Binding<String> stringBinding =
+        injector.getBinding(Key.get(String.class, Names.named("foo")));
+    ProvidesMethodBinding<String> stringMethod =
+        stringBinding.acceptTargetVisitor(new BindingCapturer<String>());
+    assertEquals(m1, stringMethod.getEnclosingInstance());
+    assertEquals(m1.getClass().getDeclaredMethod("provideFoo", Integer.class),
+        stringMethod.getMethod());
+    assertEquals(((HasDependencies) stringBinding).getDependencies(),
+        stringMethod.getDependencies());
+    assertEquals(Key.get(String.class, Names.named("foo")), stringMethod.getKey());
+    
+    Binding<Integer> intBinding = injector.getBinding(Integer.class);
+    ProvidesMethodBinding<Integer> intMethod =
+        intBinding.acceptTargetVisitor(new BindingCapturer<Integer>());
+    assertEquals(m2, intMethod.getEnclosingInstance());
+    assertEquals(m2.getClass().getDeclaredMethod("provideInt", String.class),
+        intMethod.getMethod());
+    assertEquals(((HasDependencies) intBinding).getDependencies(),
+        intMethod.getDependencies());
+    assertEquals(Key.get(Integer.class), intMethod.getKey());
+    
+  }
+  
+  private static class BindingCapturer<T> extends DefaultBindingTargetVisitor<T, ProvidesMethodBinding<T>>
+      implements ProvidesMethodTargetVisitor<T, ProvidesMethodBinding<T>> {
+    
+    @SuppressWarnings("unchecked")
+    public ProvidesMethodBinding<T> visit(
+        ProvidesMethodBinding<? extends T> providesMethodBinding) {
+      return (ProvidesMethodBinding<T>)providesMethodBinding;
+    }
+    
+    @Override protected ProvidesMethodBinding<T> visitOther(Binding<? extends T> binding) {
+      throw new IllegalStateException("unexpected visit of: " + binding);
+    }    
+  }
+}
diff --git a/core/test/com/google/inject/spi/SpiBindingsTest.java b/core/test/com/google/inject/spi/SpiBindingsTest.java
index 870c911..b470d61 100644
--- a/core/test/com/google/inject/spi/SpiBindingsTest.java
+++ b/core/test/com/google/inject/spi/SpiBindingsTest.java
@@ -118,7 +118,7 @@ public class SpiBindingsTest extends TestCase {
             binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
               @Override public Void visit(
                   ProviderInstanceBinding<? extends T> binding) {
-                assertSame(stringProvider, binding.getProviderInstance());
+                assertSame(stringProvider, binding.getUserSuppliedProvider());
                 return null;
               }
             });
@@ -359,7 +359,7 @@ public class SpiBindingsTest extends TestCase {
         bind(String.class).toProvider(new ProviderWithExtensionVisitor<String>() {
           public <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
               ProviderInstanceBinding<? extends B> binding) {
-            assertSame(this, binding.getProviderInstance());
+            assertSame(this, binding.getUserSuppliedProvider());
             // We can't always check for FailingSpiTargetVisitor,
             // because constructing the injector visits here, and we need
             // to process the binding as normal
diff --git a/core/test/com/googlecode/guice/OSGiContainerTest.java b/core/test/com/googlecode/guice/OSGiContainerTest.java
index 6cb2b1b..b91975f 100644
--- a/core/test/com/googlecode/guice/OSGiContainerTest.java
+++ b/core/test/com/googlecode/guice/OSGiContainerTest.java
@@ -58,7 +58,7 @@ public class OSGiContainerTest
   static final String AOPALLIANCE_JAR = System.getProperty("aopalliance.jar", "lib/aopalliance.jar");
 /*end[AOP]*/
   static final String JAVAX_INJECT_JAR = System.getProperty("javax.inject.jar", "lib/javax.inject.jar");
-  static final String GUAVA_JAR = System.getProperty("guava.jar", "lib/guava-11.0.2.jar");
+  static final String GUAVA_JAR = System.getProperty("guava.jar", "lib/guava-16.0.1.jar");
 
   // dynamically build test bundles
   @Override protected void setUp()
diff --git a/extensions/assistedinject/.gitignore b/extensions/assistedinject/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/assistedinject/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/assistedinject/build.xml b/extensions/assistedinject/build.xml
index 459ff9e..c74a8f2 100644
--- a/extensions/assistedinject/build.xml
+++ b/extensions/assistedinject/build.xml
@@ -13,7 +13,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/assistedinject/pom.xml b/extensions/assistedinject/pom.xml
index 1ad4362..fb7b213 100644
--- a/extensions/assistedinject/pom.xml
+++ b/extensions/assistedinject/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-assistedinject</artifactId>
diff --git a/extensions/grapher/.gitignore b/extensions/grapher/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/grapher/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/grapher/build.xml b/extensions/grapher/build.xml
index d5524dd..77f2983 100644
--- a/extensions/grapher/build.xml
+++ b/extensions/grapher/build.xml
@@ -13,7 +13,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/grapher/pom.xml b/extensions/grapher/pom.xml
index 671f35a..88e6abd 100644
--- a/extensions/grapher/pom.xml
+++ b/extensions/grapher/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-grapher</artifactId>
diff --git a/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java b/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java
index 557e850..e97f111 100644
--- a/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java
+++ b/extensions/grapher/src/com/google/inject/grapher/DefaultNodeCreator.java
@@ -26,6 +26,7 @@ import com.google.inject.spi.HasDependencies;
 import com.google.inject.spi.InjectionPoint;
 import com.google.inject.spi.InstanceBinding;
 import com.google.inject.spi.ProviderInstanceBinding;
+
 import java.lang.reflect.Member;
 import java.util.Collection;
 import java.util.List;
@@ -120,7 +121,7 @@ final class DefaultNodeCreator implements NodeCreator {
      */
     @Override public Collection<Node> visit(ProviderInstanceBinding<?> binding) {
       return ImmutableList.<Node>of(newInterfaceNode(binding), newInstanceNode(binding,
-          binding.getProviderInstance()));
+          binding.getUserSuppliedProvider()));
     }
 
     @Override public Collection<Node> visitOther(Binding<?> binding) {
diff --git a/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java b/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java
index e344f11..867a5a8 100644
--- a/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java
+++ b/extensions/grapher/test/com/google/inject/grapher/ShortNameFactoryTest.java
@@ -157,7 +157,7 @@ public class ShortNameFactoryTest extends TestCase {
         new DefaultBindingTargetVisitor<Object, Void>() {
           @SuppressWarnings("unchecked") @Override
           public Void visit(ProviderInstanceBinding<?> binding) {
-            methodHolder[0] = (ProviderMethod) binding.getProviderInstance();
+            methodHolder[0] = (ProviderMethod) binding.getUserSuppliedProvider();
             return null;
           }
         });
diff --git a/extensions/jmx/.gitignore b/extensions/jmx/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/jmx/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/jmx/build.xml b/extensions/jmx/build.xml
index 8a99b77..aeb7da7 100644
--- a/extensions/jmx/build.xml
+++ b/extensions/jmx/build.xml
@@ -13,7 +13,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/jmx/pom.xml b/extensions/jmx/pom.xml
index d5143b6..6ec2aea 100644
--- a/extensions/jmx/pom.xml
+++ b/extensions/jmx/pom.xml
@@ -6,11 +6,21 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-jmx</artifactId>
 
   <name>Sisu Guice - Extensions - JMX</name>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <skip>true</skip> <!-- Test is not actually a unit test. -->
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/extensions/jndi/.gitignore b/extensions/jndi/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/jndi/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/jndi/build.xml b/extensions/jndi/build.xml
index 5c366a2..780fceb 100644
--- a/extensions/jndi/build.xml
+++ b/extensions/jndi/build.xml
@@ -13,7 +13,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/jndi/pom.xml b/extensions/jndi/pom.xml
index 4d66075..732d545 100644
--- a/extensions/jndi/pom.xml
+++ b/extensions/jndi/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-jndi</artifactId>
diff --git a/extensions/mini/.gitignore b/extensions/mini/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/mini/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/multibindings/.gitignore b/extensions/multibindings/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/multibindings/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/multibindings/build.xml b/extensions/multibindings/build.xml
index 2f72159..f78a8e3 100644
--- a/extensions/multibindings/build.xml
+++ b/extensions/multibindings/build.xml
@@ -13,7 +13,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/multibindings/pom.xml b/extensions/multibindings/pom.xml
index ba7cf32..7a51281 100644
--- a/extensions/multibindings/pom.xml
+++ b/extensions/multibindings/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-multibindings</artifactId>
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
index d423597..f5f1a24 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
@@ -25,11 +25,15 @@ import static com.google.inject.multibindings.Multibinder.setOf;
 import static com.google.inject.util.Types.newParameterizedType;
 import static com.google.inject.util.Types.newParameterizedTypeWithOwner;
 
+import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.LinkedHashMultimap;
 import com.google.inject.Binder;
 import com.google.inject.Binding;
 import com.google.inject.Inject;
@@ -38,6 +42,7 @@ import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
+import com.google.inject.internal.Errors;
 import com.google.inject.binder.LinkedBindingBuilder;
 import com.google.inject.multibindings.Multibinder.RealMultibinder;
 import com.google.inject.spi.BindingTargetVisitor;
@@ -302,7 +307,7 @@ public abstract class MapBinder<K, V> {
    *
    * <p>We use a subclass to hide 'implements Module' from the public API.
    */
-  private static final class RealMapBinder<K, V> extends MapBinder<K, V> implements Module {
+  static final class RealMapBinder<K, V> extends MapBinder<K, V> implements Module {
     private final TypeLiteral<K> keyType;
     private final TypeLiteral<V> valueType;
     private final Key<Map<K, V>> mapKey;
@@ -377,14 +382,39 @@ public abstract class MapBinder<K, V> {
 
           Map<K, Provider<V>> providerMapMutable = new LinkedHashMap<K, Provider<V>>();
           List<Map.Entry<K, Binding<V>>> bindingsMutable = Lists.newArrayList();
+          Set<K> duplicateKeys = null;
           for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
             Provider<V> previous = providerMapMutable.put(entry.getKey(), entry.getValue());
-            checkConfiguration(previous == null || permitDuplicates,
-                "Map injection failed due to duplicated key \"%s\"", entry.getKey());
+            if (previous != null && !permitDuplicates) {
+              if (duplicateKeys == null) {
+                duplicateKeys = Sets.newHashSet();
+              }
+              duplicateKeys.add(entry.getKey());
+            }
             ProviderMapEntry<K, V> providerEntry = (ProviderMapEntry<K, V>) entry;
             Key<V> valueKey = providerEntry.getValueKey();
             bindingsMutable.add(Maps.immutableEntry(entry.getKey(), injector.getBinding(valueKey)));
           }
+          if (duplicateKeys != null) {
+            Multimap<K, String> dups = LinkedHashMultimap.create();
+            for (Map.Entry<K, Binding<V>> entry : bindingsMutable) {
+              if (duplicateKeys.contains(entry.getKey())) {
+                dups.put(entry.getKey(), "\t" + Errors.convert(entry.getValue().getSource()));
+              }
+            }
+            StringBuilder sb = new StringBuilder("Map injection failed due to duplicated key ");
+            boolean first = true;
+            for (K key : dups.keySet()) {
+              if (first) {
+                first = false;
+                sb.append("\"" + key + "\", from bindings at:\n");
+              } else {
+                sb.append("\n and key: \"" + key + "\", from bindings at:\n");
+              }
+              Joiner.on('\n').appendTo(sb, dups.get(key)).append("\n");
+            }
+            checkConfiguration(false, sb.toString());
+          }
 
           providerMap = ImmutableMap.copyOf(providerMapMutable);
           mapBindings = ImmutableList.copyOf(bindingsMutable);
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/RealElement.java b/extensions/multibindings/src/com/google/inject/multibindings/RealElement.java
index 185d647..e8e2a5d 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/RealElement.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/RealElement.java
@@ -214,6 +214,10 @@ class RealElement implements Element {
     }
 
     public ScopedBindingBuilder toProvider(Provider<? extends T> provider) {
+      return toProvider((javax.inject.Provider<T>) provider);
+    }
+
+    public ScopedBindingBuilder toProvider(javax.inject.Provider<? extends T> provider) {
       delegate.toProvider(provider);
       annotation.targetType = TargetType.PROVIDER_INSTANCE;
       annotation.target = provider;
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java b/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
index 31aeac0..caa2e74 100644
--- a/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
+++ b/extensions/multibindings/test/com/google/inject/multibindings/MapBinderTest.java
@@ -16,6 +16,7 @@
 
 package com.google.inject.multibindings;
 
+import static com.google.inject.Asserts.asModuleChain;
 import static com.google.inject.Asserts.assertContains;
 import static com.google.inject.multibindings.SpiUtils.VisitType.BOTH;
 import static com.google.inject.multibindings.SpiUtils.VisitType.MODULE;
@@ -40,6 +41,7 @@ import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.Provider;
+import com.google.inject.Provides;
 import com.google.inject.ProvisionException;
 import com.google.inject.Stage;
 import com.google.inject.TypeLiteral;
@@ -82,7 +84,6 @@ public class MapBinderTest extends TestCase {
       
   private final TypeLiteral<String> stringType = TypeLiteral.get(String.class);
   private final TypeLiteral<Integer> intType = TypeLiteral.get(Integer.class);
-  private final TypeLiteral<Set<String>> stringSetType = new TypeLiteral<Set<String>>() {};
 
   public void testMapBinderAggregatesMultipleModules() {
     Module abc = new AbstractModule() {
@@ -327,6 +328,56 @@ public class MapBinderTest extends TestCase {
         instance("a", "A"), instance("a", "B"));
   }
 
+  public void testExhaustiveDuplicateErrorMessage() throws Exception {
+    class Module1 extends AbstractModule {
+      @Override protected void configure() {
+        MapBinder<String, Object> mapbinder =
+            MapBinder.newMapBinder(binder(), String.class, Object.class);
+        mapbinder.addBinding("a").to(String.class);
+      }
+    }
+    class Module2 extends AbstractModule {
+      @Override protected void configure() {
+        MapBinder<String, Object> mapbinder =
+            MapBinder.newMapBinder(binder(), String.class, Object.class);
+        mapbinder.addBinding("a").to(Integer.class);
+        mapbinder.addBinding("b").to(String.class);
+      }
+    }
+    class Module3 extends AbstractModule {
+      @Override protected void configure() {
+        MapBinder<String, Object> mapbinder =
+            MapBinder.newMapBinder(binder(), String.class, Object.class);
+        mapbinder.addBinding("b").to(Integer.class);
+      }
+    }
+    class Main extends AbstractModule {
+      @Override protected void configure() {
+        MapBinder.newMapBinder(binder(), String.class, Object.class);
+        install(new Module1());
+        install(new Module2());
+        install(new Module3());
+      }
+      @Provides String provideString() { return "foo"; }
+      @Provides Integer provideInt() { return 42; }
+    }
+    try {
+      Guice.createInjector(new Main());
+      fail();
+    } catch(CreationException ce) {
+      assertContains(ce.getMessage(),
+          "Map injection failed due to duplicated key \"a\", from bindings at:",
+          asModuleChain(Main.class, Module1.class),
+          asModuleChain(Main.class, Module2.class),
+          "and key: \"b\", from bindings at:",
+          asModuleChain(Main.class, Module2.class),
+          asModuleChain(Main.class, Module3.class),
+          "at " + Main.class.getName() + ".configure(",
+          asModuleChain(Main.class, MapBinder.RealMapBinder.class));
+      assertEquals(1, ce.getErrorMessages().size());
+    }
+  }
+
   public void testMapBinderMapPermitDuplicateElements() {
     Module ab = new AbstractModule() {
       @Override protected void configure() {
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java b/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
index 2589f5d..829fe3b 100644
--- a/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
+++ b/extensions/multibindings/test/com/google/inject/multibindings/SpiUtils.java
@@ -135,7 +135,7 @@ public class SpiUtils {
           break;
         case PROVIDER_INSTANCE:
           if (value instanceof ProviderInstanceBinding
-              && ((ProviderInstanceBinding) value).getProviderInstance().get().equals(
+              && ((ProviderInstanceBinding) value).getUserSuppliedProvider().get().equals(
                   result.v.instance)) {
             found = entry;
           }
@@ -376,7 +376,7 @@ public class SpiUtils {
           break;
         case PROVIDER_INSTANCE:
           if (item instanceof ProviderInstanceBinding
-              && ((ProviderInstanceBinding) item).getProviderInstance().get().equals(
+              && ((ProviderInstanceBinding) item).getUserSuppliedProvider().get().equals(
                   result.instance)) {
             found = item;
           }
diff --git a/extensions/persist/.gitignore b/extensions/persist/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/persist/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/persist/build.xml b/extensions/persist/build.xml
index 764c726..3cc6a4f 100644
--- a/extensions/persist/build.xml
+++ b/extensions/persist/build.xml
@@ -14,7 +14,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/persist/pom.xml b/extensions/persist/pom.xml
index bda1877..f0f1440 100644
--- a/extensions/persist/pom.xml
+++ b/extensions/persist/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-persist</artifactId>
@@ -44,17 +44,18 @@
       <version>2.0.0</version>
       <scope>test</scope>
     </dependency>
+    <!-- These are present for IDEs which will not be pulling in the jarjar'ed value. -->
+    <dependency>
+      <groupId>cglib</groupId>
+      <artifactId>cglib</artifactId>
+      <version>3.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm-util</artifactId>
+      <version>4.0</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <forkMode>never</forkMode>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
 </project>
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java b/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
index 942835f..1f59a6d 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/JpaLocalTxnInterceptor.java
@@ -33,11 +33,12 @@ import javax.persistence.EntityTransaction;
  */
 class JpaLocalTxnInterceptor implements MethodInterceptor {
 
+  // TODO(gak): Move these args to the cxtor & make these final.
   @Inject
-  private final JpaPersistService emProvider = null;
+  private JpaPersistService emProvider = null;
 
   @Inject
-  private final UnitOfWork unitOfWork = null;
+  private UnitOfWork unitOfWork = null;
 
   @Transactional
   private static class Internal {}
diff --git a/extensions/persist/test/com/google/inject/persist/EdslTest.java b/extensions/persist/test/com/google/inject/persist/EdslTest.java
index 9fd502f..81e0b6b 100644
--- a/extensions/persist/test/com/google/inject/persist/EdslTest.java
+++ b/extensions/persist/test/com/google/inject/persist/EdslTest.java
@@ -4,7 +4,7 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Stage;
 import com.google.inject.persist.jpa.JpaPersistModule;
-
+import java.util.logging.Logger;
 import junit.framework.TestCase;
 
 /**
@@ -13,12 +13,14 @@ import junit.framework.TestCase;
 public class EdslTest extends TestCase {
 
   public void testModuleConfigUsingJpa() throws Exception {
+    Logger.getLogger(getClass().getName()).info("Starting EDSL test.");
     Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
       @Override
       protected void configure() {
         install(new JpaPersistModule("myunit"));
         binder().requireExplicitBindings();
-      };
+      }
     });
+    Logger.getLogger(getClass().getName()).info("Completed EDSL test.");
   }
 }
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 5e282e9..5777223 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>guice-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <packaging>pom</packaging>
@@ -54,6 +54,16 @@
       <classifier>tests</classifier>
       <scope>test</scope>
     </dependency>
+    <!--
+     | Some extension tests depend on cglib which is not embedded
+     | in an execution that doesn't include package.
+    -->
+    <dependency>
+      <groupId>cglib</groupId>
+      <artifactId>cglib</artifactId>
+      <version>3.1</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
@@ -65,7 +75,7 @@
         <artifactId>maven-remote-resources-plugin</artifactId>
       </plugin>
       <!--
-       | Enable Java5 conformance checks
+       | Enable Java6 conformance checks
       -->
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
@@ -85,33 +95,4 @@
       </plugin>
     </plugins>
   </build>
-
-  <profiles>
-    <profile>
-      <!--
-       | If JarJar build profile is disabled we need CGLIB during tests
-      -->
-      <activation>
-        <property>
-          <name>guice.with.jarjar</name>
-          <value>false</value>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.ow2.asm</groupId>
-          <artifactId>asm</artifactId>
-          <version>5.0_BETA</version>
-          <scope>test</scope>
-        </dependency>
-        <dependency>
-          <groupId>cglib</groupId>
-          <artifactId>cglib</artifactId>
-          <version>3.1</version>
-          <scope>test</scope>
-        </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
-
 </project>
diff --git a/extensions/service/.gitignore b/extensions/service/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/service/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/servlet/.gitignore b/extensions/servlet/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/servlet/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/servlet/build.xml b/extensions/servlet/build.xml
index 5bee7e5..0ef5039 100644
--- a/extensions/servlet/build.xml
+++ b/extensions/servlet/build.xml
@@ -15,7 +15,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/servlet/pom.xml b/extensions/servlet/pom.xml
index b9894e5..2158e15 100644
--- a/extensions/servlet/pom.xml
+++ b/extensions/servlet/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-servlet</artifactId>
diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java b/extensions/servlet/src/com/google/inject/servlet/AbstractFilterPipeline.java
similarity index 73%
copy from extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
copy to extensions/servlet/src/com/google/inject/servlet/AbstractFilterPipeline.java
index 9e5b849..9ab0124 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/AbstractFilterPipeline.java
@@ -15,18 +15,12 @@
  */
 package com.google.inject.servlet;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import com.google.inject.Binding;
-import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import com.google.inject.TypeLiteral;
 
 import java.io.IOException;
-import java.util.List;
 import java.util.Set;
 
 import javax.servlet.Filter;
@@ -45,10 +39,13 @@ import javax.servlet.http.HttpServletRequestWrapper;
  *
  * @author dhanji at gmail.com (Dhanji R. Prasanna)
  */
- at Singleton
-class ManagedFilterPipeline implements FilterPipeline{
-  private final FilterDefinition[] filterDefinitions;
-  private final ManagedServletPipeline servletPipeline;
+public abstract class AbstractFilterPipeline implements FilterPipeline {
+
+  protected abstract boolean hasFiltersMapped();
+
+  protected abstract FilterDefinition[] filterDefinitions();
+
+  private final AbstractServletPipeline servletPipeline;
   private final Provider<ServletContext> servletContext;
 
   //Unfortunately, we need the injector itself in order to create filters + servlets
@@ -56,34 +53,12 @@ class ManagedFilterPipeline implements FilterPipeline{
 
   //Guards a DCL, so needs to be volatile
   private volatile boolean initialized = false;
-  private static final TypeLiteral<FilterDefinition> FILTER_DEFS =
-      TypeLiteral.get(FilterDefinition.class);
 
-  @Inject
-  public ManagedFilterPipeline(Injector injector, ManagedServletPipeline servletPipeline,
+  protected AbstractFilterPipeline(Injector injector, AbstractServletPipeline servletPipeline,
       Provider<ServletContext> servletContext) {
     this.injector = injector;
     this.servletPipeline = servletPipeline;
     this.servletContext = servletContext;
-
-    this.filterDefinitions = collectFilterDefinitions(injector);
-  }
-
-  /**
-   * Introspects the injector and collects all instances of bound {@code List<FilterDefinition>}
-   * into a master list.
-   * 
-   * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
-   * that preserves insertion order in entry-set iterators.
-   */
-  private FilterDefinition[] collectFilterDefinitions(Injector injector) {
-    List<FilterDefinition> filterDefinitions = Lists.newArrayList();
-    for (Binding<FilterDefinition> entry : injector.findBindingsByType(FILTER_DEFS)) {
-      filterDefinitions.add(entry.getProvider().get());
-    }
-    
-    // Copy to a fixed-size array for speed of iteration.
-    return filterDefinitions.toArray(new FilterDefinition[filterDefinitions.size()]);
   }
 
   public synchronized void initPipeline(ServletContext servletContext)
@@ -96,7 +71,7 @@ class ManagedFilterPipeline implements FilterPipeline{
     // Used to prevent duplicate initialization.
     Set<Filter> initializedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
 
-    for (FilterDefinition filterDefinition : filterDefinitions) {
+    for (FilterDefinition filterDefinition : filterDefinitions()) {
       filterDefinition.init(servletContext, injector, initializedSoFar);
     }
 
@@ -117,7 +92,7 @@ class ManagedFilterPipeline implements FilterPipeline{
     }
 
     //obtain the servlet pipeline to dispatch against
-    new FilterChainInvocation(filterDefinitions, servletPipeline, proceedingFilterChain)
+    new FilterChainInvocation(filterDefinitions(), servletPipeline, proceedingFilterChain)
         .doFilter(withDispatcher(request, servletPipeline), response);
 
   }
@@ -134,8 +109,8 @@ class ManagedFilterPipeline implements FilterPipeline{
    * incrementally, but not the other way around (which, we should actively discourage).
    */
   @SuppressWarnings({ "JavaDoc", "deprecation" })
-  private ServletRequest withDispatcher(ServletRequest servletRequest,
-      final ManagedServletPipeline servletPipeline) {
+  private static ServletRequest withDispatcher(ServletRequest servletRequest,
+      final AbstractServletPipeline servletPipeline) {
 
     // don't wrap the request if there are no servlets mapped. This prevents us from inserting our
     // wrapper unless it's actually going to be used. This is necessary for compatibility for apps
@@ -163,7 +138,7 @@ class ManagedFilterPipeline implements FilterPipeline{
 
     //go down chain and destroy all our filters
     Set<Filter> destroyedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
-    for (FilterDefinition filterDefinition : filterDefinitions) {
+    for (FilterDefinition filterDefinition : filterDefinitions()) {
       filterDefinition.destroy(destroyedSoFar);
     }
   }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java b/extensions/servlet/src/com/google/inject/servlet/AbstractServletPipeline.java
similarity index 80%
copy from extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
copy to extensions/servlet/src/com/google/inject/servlet/AbstractServletPipeline.java
index e3e35df..00d849e 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/AbstractServletPipeline.java
@@ -16,17 +16,11 @@
 package com.google.inject.servlet;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import com.google.inject.Binding;
-import com.google.inject.Inject;
 import com.google.inject.Injector;
-import com.google.inject.Singleton;
-import com.google.inject.TypeLiteral;
 
 import java.io.IOException;
-import java.util.List;
 import java.util.Set;
 
 import javax.servlet.RequestDispatcher;
@@ -44,43 +38,17 @@ import javax.servlet.http.HttpServletRequestWrapper;
  *
  * @author dhanji at gmail.com (Dhanji R. Prasanna)
  */
- at Singleton
-class ManagedServletPipeline {
-  private final ServletDefinition[] servletDefinitions;
-  private static final TypeLiteral<ServletDefinition> SERVLET_DEFS =
-      TypeLiteral.get(ServletDefinition.class);
-
-  @Inject
-  public ManagedServletPipeline(Injector injector) {
-    this.servletDefinitions = collectServletDefinitions(injector);
-  }
+public abstract class AbstractServletPipeline {
 
-  boolean hasServletsMapped() {
-    return servletDefinitions.length > 0;
-  }
+  protected abstract boolean hasServletsMapped();
 
-  /**
-   * Introspects the injector and collects all instances of bound {@code List<ServletDefinition>}
-   * into a master list.
-   *
-   * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
-   * that preserves insertion order in entry-set iterators.
-   */
-  private ServletDefinition[] collectServletDefinitions(Injector injector) {
-    List<ServletDefinition> servletDefinitions = Lists.newArrayList();
-    for (Binding<ServletDefinition> entry : injector.findBindingsByType(SERVLET_DEFS)) {
-        servletDefinitions.add(entry.getProvider().get());
-    }
-
-    // Copy to a fixed size array for speed.
-    return servletDefinitions.toArray(new ServletDefinition[servletDefinitions.size()]);
-  }
+  protected abstract ServletDefinition[] servletDefinitions();
 
   public void init(ServletContext servletContext, Injector injector) throws ServletException {
     Set<HttpServlet> initializedSoFar
         = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
 
-    for (ServletDefinition servletDefinition : servletDefinitions) {
+    for (ServletDefinition servletDefinition : servletDefinitions()) {
       servletDefinition.init(servletContext, injector, initializedSoFar);
     }
   }
@@ -89,7 +57,7 @@ class ManagedServletPipeline {
       throws IOException, ServletException {
 
     //stop at the first matching servlet and service
-    for (ServletDefinition servletDefinition : servletDefinitions) {
+    for (ServletDefinition servletDefinition : servletDefinitions()) {
       if (servletDefinition.service(request, response)) {
         return true;
       }
@@ -102,7 +70,7 @@ class ManagedServletPipeline {
   public void destroy() {
     Set<HttpServlet> destroyedSoFar
         = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
-    for (ServletDefinition servletDefinition : servletDefinitions) {
+    for (ServletDefinition servletDefinition : servletDefinitions()) {
       servletDefinition.destroy(destroyedSoFar);
     }
   }
@@ -117,7 +85,7 @@ class ManagedServletPipeline {
     // TODO(dhanji): check servlet spec to see if the following is legal or not.
     // Need to strip query string if requested...
 
-    for (final ServletDefinition servletDefinition : servletDefinitions) {
+    for (final ServletDefinition servletDefinition : servletDefinitions()) {
       if (servletDefinition.shouldServe(path)) {
         return new RequestDispatcher() {
           public void forward(ServletRequest servletRequest, ServletResponse servletResponse)
diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
index b4112cf..bfe5a83 100644
--- a/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FilterChainInvocation.java
@@ -50,7 +50,7 @@ class FilterChainInvocation implements FilterChain {
   
   private final FilterDefinition[] filterDefinitions;
   private final FilterChain proceedingChain;
-  private final ManagedServletPipeline servletPipeline;
+  private final AbstractServletPipeline servletPipeline;
 
   //state variable tracks current link in filterchain
   private int index = -1;
@@ -58,7 +58,7 @@ class FilterChainInvocation implements FilterChain {
   private boolean cleanedStacks = false;
 
   public FilterChainInvocation(FilterDefinition[] filterDefinitions,
-      ManagedServletPipeline servletPipeline, FilterChain proceedingChain) {
+      AbstractServletPipeline servletPipeline, FilterChain proceedingChain) {
 
     this.filterDefinitions = filterDefinitions;
     this.servletPipeline = servletPipeline;
diff --git a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
index ff1e5b6..dc09014 100644
--- a/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
+++ b/extensions/servlet/src/com/google/inject/servlet/FilterDefinition.java
@@ -15,6 +15,7 @@
  */
 package com.google.inject.servlet;
 
+import com.google.common.base.Strings;
 import com.google.common.collect.Iterators;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -29,6 +30,8 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterConfig;
@@ -41,7 +44,9 @@ import javax.servlet.http.HttpServletRequest;
  *
  * @author dhanji at gmail.com (Dhanji R. Prasanna)
  */
-class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition> {
+public class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition> {
+  private static final Logger logger = Logger.getLogger(FilterDefinition.class.getName());
+
   private final String pattern;
   private final Key<? extends Filter> filterKey;
   private final UriPatternMatcher patternMatcher;
@@ -154,7 +159,11 @@ class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition>
 
     final String path = ServletUtils.getContextRelativePath(request);
     if (shouldFilter(path)) {
-      return filter.get();
+      Filter reference = filter.get();
+      if (logger.isLoggable(Level.FINEST)) {
+        logger.finest("Filtering " + path + " with " + reference);
+      }
+      return reference;
     } else {
       return null;
     }
@@ -164,4 +173,10 @@ class FilterDefinition implements ProviderWithExtensionVisitor<FilterDefinition>
   Filter getFilter() {
     return filter.get();
   }
+
+  public String toPaddedString(int padding) {
+    Filter reference = filter.get();
+    return Strings.padEnd(pattern, padding, ' ') + ' '
+        + (reference != null ? reference : filterKey);
+  }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java b/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
index 2913e55..7ab0cdf 100644
--- a/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
+++ b/extensions/servlet/src/com/google/inject/servlet/GuiceFilter.java
@@ -19,7 +19,9 @@ package com.google.inject.servlet;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
 import com.google.inject.Inject;
+import com.google.inject.Key;
 import com.google.inject.OutOfScopeException;
+import com.google.inject.internal.Errors;
 
 import java.io.IOException;
 import java.lang.ref.WeakReference;
@@ -98,9 +100,9 @@ public class GuiceFilter implements Filter {
 
     // This can happen if you create many injectors and they all have their own
     // servlet module. This is legal, caveat a small warning.
-    if (GuiceFilter.pipeline instanceof ManagedFilterPipeline) {
-      LOGGER.config(MULTIPLE_INJECTORS_WARNING);
-    }
+    //if (GuiceFilter.pipeline instanceof ManagedFilterPipeline) {
+    //  LOGGER.config(MULTIPLE_INJECTORS_WARNING);
+    //}
 
     // We overwrite the default pipeline
     GuiceFilter.pipeline = pipeline;
@@ -142,27 +144,27 @@ public class GuiceFilter implements Filter {
     }
   }
 
-  static HttpServletRequest getOriginalRequest() {
-    return getContext().getOriginalRequest();
+  static HttpServletRequest getOriginalRequest(Key<?> key) {
+    return getContext(key).getOriginalRequest();
   }
 
-  static HttpServletRequest getRequest() {
-    return getContext().getRequest();
+  static HttpServletRequest getRequest(Key<?> key) {
+    return getContext(key).getRequest();
   }
 
-  static HttpServletResponse getResponse() {
-    return getContext().getResponse();
+  static HttpServletResponse getResponse(Key<?> key) {
+    return getContext(key).getResponse();
   }
 
   static ServletContext getServletContext() {
     return servletContext.get();
   }
 
-  private static Context getContext() {
+  private static Context getContext(Key<?> key) {
     Context context = localContext.get();
     if (context == null) {
-      throw new OutOfScopeException("Cannot access scoped object. Either we"
-          + " are not currently inside an HTTP Servlet request, or you may"
+      throw new OutOfScopeException("Cannot access scoped [" + Errors.convert(key) 
+          + "]. Either we are not currently inside an HTTP Servlet request, or you may"
           + " have forgotten to apply " + GuiceFilter.class.getName()
           + " as a servlet filter for this request.");
     }
diff --git a/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java b/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
index 8043ca9..046b8b6 100644
--- a/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
+++ b/extensions/servlet/src/com/google/inject/servlet/InternalServletModule.java
@@ -20,6 +20,7 @@ import static com.google.inject.servlet.ServletScopes.SESSION;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
+import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
@@ -102,15 +103,15 @@ final class InternalServletModule extends AbstractModule {
   }
 
   @Provides @RequestScoped HttpServletRequest provideHttpServletRequest() {
-    return GuiceFilter.getRequest();
+    return GuiceFilter.getRequest(Key.get(HttpServletRequest.class));
   }
 
   @Provides @RequestScoped HttpServletResponse provideHttpServletResponse() {
-    return GuiceFilter.getResponse();
+    return GuiceFilter.getResponse(Key.get(HttpServletResponse.class));
   }
 
   @Provides HttpSession provideHttpSession() {
-    return GuiceFilter.getRequest().getSession();
+    return GuiceFilter.getRequest(Key.get(HttpSession.class)).getSession();
   }
 
   @SuppressWarnings("unchecked") // defined by getParameterMap()
diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java b/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
index 9e5b849..47bfec9 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ManagedFilterPipeline.java
@@ -16,8 +16,6 @@
 package com.google.inject.servlet;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 import com.google.inject.Binding;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
@@ -25,19 +23,9 @@ import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.TypeLiteral;
 
-import java.io.IOException;
 import java.util.List;
-import java.util.Set;
 
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
 
 /**
  * Central routing/dispatch class handles lifecycle of managed filters, and delegates to the servlet
@@ -46,29 +34,28 @@ import javax.servlet.http.HttpServletRequestWrapper;
  * @author dhanji at gmail.com (Dhanji R. Prasanna)
  */
 @Singleton
-class ManagedFilterPipeline implements FilterPipeline{
+class ManagedFilterPipeline extends AbstractFilterPipeline {
   private final FilterDefinition[] filterDefinitions;
-  private final ManagedServletPipeline servletPipeline;
-  private final Provider<ServletContext> servletContext;
-
-  //Unfortunately, we need the injector itself in order to create filters + servlets
-  private final Injector injector;
-
-  //Guards a DCL, so needs to be volatile
-  private volatile boolean initialized = false;
   private static final TypeLiteral<FilterDefinition> FILTER_DEFS =
       TypeLiteral.get(FilterDefinition.class);
 
   @Inject
   public ManagedFilterPipeline(Injector injector, ManagedServletPipeline servletPipeline,
       Provider<ServletContext> servletContext) {
-    this.injector = injector;
-    this.servletPipeline = servletPipeline;
-    this.servletContext = servletContext;
-
+    super(injector, servletPipeline, servletContext);
     this.filterDefinitions = collectFilterDefinitions(injector);
   }
 
+  @Override
+  protected boolean hasFiltersMapped() {
+    return filterDefinitions.length > 0;
+  }
+
+  @Override
+  protected FilterDefinition[] filterDefinitions() {
+    return filterDefinitions;
+  }
+
   /**
    * Introspects the injector and collects all instances of bound {@code List<FilterDefinition>}
    * into a master list.
@@ -76,7 +63,7 @@ class ManagedFilterPipeline implements FilterPipeline{
    * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
    * that preserves insertion order in entry-set iterators.
    */
-  private FilterDefinition[] collectFilterDefinitions(Injector injector) {
+  private static FilterDefinition[] collectFilterDefinitions(Injector injector) {
     List<FilterDefinition> filterDefinitions = Lists.newArrayList();
     for (Binding<FilterDefinition> entry : injector.findBindingsByType(FILTER_DEFS)) {
       filterDefinitions.add(entry.getProvider().get());
@@ -85,86 +72,4 @@ class ManagedFilterPipeline implements FilterPipeline{
     // Copy to a fixed-size array for speed of iteration.
     return filterDefinitions.toArray(new FilterDefinition[filterDefinitions.size()]);
   }
-
-  public synchronized void initPipeline(ServletContext servletContext)
-      throws ServletException {
-
-    //double-checked lock, prevents duplicate initialization
-    if (initialized)
-      return;
-
-    // Used to prevent duplicate initialization.
-    Set<Filter> initializedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
-
-    for (FilterDefinition filterDefinition : filterDefinitions) {
-      filterDefinition.init(servletContext, injector, initializedSoFar);
-    }
-
-    //next, initialize servlets...
-    servletPipeline.init(servletContext, injector);
-
-    //everything was ok...
-    initialized = true;
-  }
-
-  public void dispatch(ServletRequest request, ServletResponse response,
-      FilterChain proceedingFilterChain) throws IOException, ServletException {
-
-    //lazy init of filter pipeline (OK by the servlet specification). This is needed
-    //in order for us not to force users to create a GuiceServletContextListener subclass.
-    if (!initialized) {
-      initPipeline(servletContext.get());
-    }
-
-    //obtain the servlet pipeline to dispatch against
-    new FilterChainInvocation(filterDefinitions, servletPipeline, proceedingFilterChain)
-        .doFilter(withDispatcher(request, servletPipeline), response);
-
-  }
-
-  /**
-   * Used to create an proxy that dispatches either to the guice-servlet pipeline or the regular
-   * pipeline based on uri-path match. This proxy also provides minimal forwarding support.
-   *
-   * We cannot forward from a web.xml Servlet/JSP to a guice-servlet (because the filter pipeline
-   * is not called again). However, we can wrap requests with our own dispatcher to forward the
-   * *other* way. web.xml Servlets/JSPs can forward to themselves as per normal.
-   *
-   * This is not a problem cuz we intend for people to migrate from web.xml to guice-servlet,
-   * incrementally, but not the other way around (which, we should actively discourage).
-   */
-  @SuppressWarnings({ "JavaDoc", "deprecation" })
-  private ServletRequest withDispatcher(ServletRequest servletRequest,
-      final ManagedServletPipeline servletPipeline) {
-
-    // don't wrap the request if there are no servlets mapped. This prevents us from inserting our
-    // wrapper unless it's actually going to be used. This is necessary for compatibility for apps
-    // that downcast their HttpServletRequests to a concrete implementation.
-    if (!servletPipeline.hasServletsMapped()) {
-      return servletRequest;
-    }
-
-    HttpServletRequest request = (HttpServletRequest) servletRequest;
-    //noinspection OverlyComplexAnonymousInnerClass
-    return new HttpServletRequestWrapper(request) {
-
-      @Override
-      public RequestDispatcher getRequestDispatcher(String path) {
-        final RequestDispatcher dispatcher = servletPipeline.getRequestDispatcher(path);
-
-        return (null != dispatcher) ? dispatcher : super.getRequestDispatcher(path);
-      }
-    };
-  }
-
-  public void destroyPipeline() {
-    //destroy servlets first
-    servletPipeline.destroy();
-
-    //go down chain and destroy all our filters
-    Set<Filter> destroyedSoFar = Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap());
-    for (FilterDefinition filterDefinition : filterDefinitions) {
-      filterDefinition.destroy(destroyedSoFar);
-    }
-  }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java b/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
index e3e35df..3530c06 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ManagedServletPipeline.java
@@ -15,28 +15,14 @@
  */
 package com.google.inject.servlet;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 import com.google.inject.Binding;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
 import com.google.inject.TypeLiteral;
 
-import java.io.IOException;
 import java.util.List;
-import java.util.Set;
-
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
 
 /**
  * A wrapping dispatcher for servlets, in much the same way as {@link ManagedFilterPipeline} is for
@@ -45,7 +31,7 @@ import javax.servlet.http.HttpServletRequestWrapper;
  * @author dhanji at gmail.com (Dhanji R. Prasanna)
  */
 @Singleton
-class ManagedServletPipeline {
+class ManagedServletPipeline extends AbstractServletPipeline {
   private final ServletDefinition[] servletDefinitions;
   private static final TypeLiteral<ServletDefinition> SERVLET_DEFS =
       TypeLiteral.get(ServletDefinition.class);
@@ -55,10 +41,16 @@ class ManagedServletPipeline {
     this.servletDefinitions = collectServletDefinitions(injector);
   }
 
-  boolean hasServletsMapped() {
+  @Override
+  protected boolean hasServletsMapped() {
     return servletDefinitions.length > 0;
   }
 
+  @Override
+  protected ServletDefinition[] servletDefinitions() {
+    return servletDefinitions;
+  }
+
   /**
    * Introspects the injector and collects all instances of bound {@code List<ServletDefinition>}
    * into a master list.
@@ -66,7 +58,7 @@ class ManagedServletPipeline {
    * We have a guarantee that {@link com.google.inject.Injector#getBindings()} returns a map
    * that preserves insertion order in entry-set iterators.
    */
-  private ServletDefinition[] collectServletDefinitions(Injector injector) {
+  private static ServletDefinition[] collectServletDefinitions(Injector injector) {
     List<ServletDefinition> servletDefinitions = Lists.newArrayList();
     for (Binding<ServletDefinition> entry : injector.findBindingsByType(SERVLET_DEFS)) {
         servletDefinitions.add(entry.getProvider().get());
@@ -75,116 +67,4 @@ class ManagedServletPipeline {
     // Copy to a fixed size array for speed.
     return servletDefinitions.toArray(new ServletDefinition[servletDefinitions.size()]);
   }
-
-  public void init(ServletContext servletContext, Injector injector) throws ServletException {
-    Set<HttpServlet> initializedSoFar
-        = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
-
-    for (ServletDefinition servletDefinition : servletDefinitions) {
-      servletDefinition.init(servletContext, injector, initializedSoFar);
-    }
-  }
-
-  public boolean service(ServletRequest request, ServletResponse response)
-      throws IOException, ServletException {
-
-    //stop at the first matching servlet and service
-    for (ServletDefinition servletDefinition : servletDefinitions) {
-      if (servletDefinition.service(request, response)) {
-        return true;
-      }
-    }
-
-    //there was no match...
-    return false;
-  }
-
-  public void destroy() {
-    Set<HttpServlet> destroyedSoFar
-        = Sets.newSetFromMap(Maps.<HttpServlet, Boolean>newIdentityHashMap());
-    for (ServletDefinition servletDefinition : servletDefinitions) {
-      servletDefinition.destroy(destroyedSoFar);
-    }
-  }
-
-  /**
-   * @return Returns a request dispatcher wrapped with a servlet mapped to
-   * the given path or null if no mapping was found.
-   */
-  RequestDispatcher getRequestDispatcher(String path) {
-    final String newRequestUri = path;
-
-    // TODO(dhanji): check servlet spec to see if the following is legal or not.
-    // Need to strip query string if requested...
-
-    for (final ServletDefinition servletDefinition : servletDefinitions) {
-      if (servletDefinition.shouldServe(path)) {
-        return new RequestDispatcher() {
-          public void forward(ServletRequest servletRequest, ServletResponse servletResponse)
-              throws ServletException, IOException {
-            Preconditions.checkState(!servletResponse.isCommitted(),
-                "Response has been committed--you can only call forward before"
-                + " committing the response (hint: don't flush buffers)");
-
-            // clear buffer before forwarding
-            servletResponse.resetBuffer();
-
-            ServletRequest requestToProcess;
-            if (servletRequest instanceof HttpServletRequest) {
-               requestToProcess = new RequestDispatcherRequestWrapper(servletRequest, newRequestUri);
-            } else {
-              // This should never happen, but instead of throwing an exception
-              // we will allow a happy case pass thru for maximum tolerance to
-              // legacy (and internal) code.
-              requestToProcess = servletRequest;
-            }
-
-            // now dispatch to the servlet
-            doServiceImpl(servletDefinition, requestToProcess, servletResponse);
-          }
-
-          public void include(ServletRequest servletRequest, ServletResponse servletResponse)
-              throws ServletException, IOException {
-            // route to the target servlet
-            doServiceImpl(servletDefinition, servletRequest, servletResponse);
-          }
-
-          private void doServiceImpl(ServletDefinition servletDefinition, ServletRequest servletRequest,
-              ServletResponse servletResponse) throws ServletException, IOException {
-            servletRequest.setAttribute(REQUEST_DISPATCHER_REQUEST, Boolean.TRUE);
-
-            try {
-              servletDefinition.doService(servletRequest, servletResponse);
-            } finally {
-              servletRequest.removeAttribute(REQUEST_DISPATCHER_REQUEST);
-            }
-          }
-        };
-      }
-    }
-
-    //otherwise, can't process
-    return null;
-  }
-
-  /**
-   * A Marker constant attribute that when present in the request indicates to Guice servlet that
-   * this request has been generated by a request dispatcher rather than the servlet pipeline.
-   * In accordance with section 8.4.2 of the Servlet 2.4 specification.
-   */
-  public static final String REQUEST_DISPATCHER_REQUEST = "javax.servlet.forward.servlet_path";
-
-  private static class RequestDispatcherRequestWrapper extends HttpServletRequestWrapper {
-    private final String newRequestUri;
-
-    public RequestDispatcherRequestWrapper(ServletRequest servletRequest, String newRequestUri) {
-      super((HttpServletRequest) servletRequest);
-      this.newRequestUri = newRequestUri;
-    }
-
-    @Override
-    public String getRequestURI() {
-      return newRequestUri;
-    }
-  }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java b/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
index cbd8f29..99a408a 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
@@ -17,6 +17,7 @@ package com.google.inject.servlet;
 
 import static com.google.inject.servlet.ManagedServletPipeline.REQUEST_DISPATCHER_REQUEST;
 
+import com.google.common.base.Strings;
 import com.google.common.collect.Iterators;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -34,6 +35,8 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -51,7 +54,9 @@ import javax.servlet.http.HttpServletResponse;
  *
  * @author dhanji at gmail.com (Dhanji R. Prasanna)
  */
-class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinition> {
+public class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinition> {
+  private static final Logger logger = Logger.getLogger(ServletDefinition.class.getName());
+
   private final String pattern;
   private final Key<? extends HttpServlet> servletKey;
   private final UriPatternMatcher patternMatcher;
@@ -285,7 +290,14 @@ class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinitio
         = (previous != null) ? previous.getOriginalRequest() : request;
     GuiceFilter.localContext.set(new GuiceFilter.Context(originalRequest, request, response));
     try {
-      httpServlet.get().service(request, response);
+      HttpServlet reference = httpServlet.get();
+      if (logger.isLoggable(Level.FINEST)) {
+        String path = ServletUtils.getContextRelativePath(request);
+        logger.finest("Serving " + path + " with " + reference);
+      }
+      if (reference != null) {
+        reference.service(request, response);
+      }
     } finally {
       GuiceFilter.localContext.set(previous);
     }
@@ -298,4 +310,10 @@ class ServletDefinition implements ProviderWithExtensionVisitor<ServletDefinitio
   String getPattern() {
     return pattern;
   }
+
+  public String toPaddedString(int padding) {
+    HttpServlet reference = httpServlet.get();
+    return Strings.padEnd(pattern, padding, ' ') + ' '
+        + (reference != null ? reference : servletKey);
+  }
 }
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
index 5acf653..9d4e278 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
@@ -19,6 +19,7 @@ package com.google.inject.servlet;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Maps.EntryTransformer;
 import com.google.inject.Binding;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -102,7 +103,7 @@ public class ServletScopes {
           // {@code GuiceFilter.getRequest()}.
           //
           // This _correctly_ throws up if the thread is out of scope.
-          HttpServletRequest request = GuiceFilter.getOriginalRequest();
+          HttpServletRequest request = GuiceFilter.getOriginalRequest(key);
           if (REQUEST_CONTEXT_KEYS.contains(key)) {
             // Don't store these keys as attributes, since they are handled by
             // GuiceFilter itself.
@@ -143,11 +144,11 @@ public class ServletScopes {
    * HTTP session scope.
    */
   public static final Scope SESSION = new Scope() {
-    public <T> Provider<T> scope(Key<T> key, final Provider<T> creator) {
+    public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
       final String name = key.toString();
       return new Provider<T>() {
         public T get() {
-          HttpSession session = GuiceFilter.getRequest().getSession();
+          HttpSession session = GuiceFilter.getRequest(key).getSession();
           synchronized (session) {
             Object obj = session.getAttribute(name);
             if (NullObject.INSTANCE == obj) {
@@ -216,7 +217,8 @@ public class ServletScopes {
 
     // Snapshot the seed map and add all the instances to our continuing HTTP request.
     final ContinuingHttpServletRequest continuingRequest =
-        new ContinuingHttpServletRequest(GuiceFilter.getRequest());
+        new ContinuingHttpServletRequest(
+            GuiceFilter.getRequest(Key.get(HttpServletRequest.class)));
     for (Map.Entry<Key<?>, Object> entry : seedMap.entrySet()) {
       Object value = validateAndCanonicalizeValue(entry.getKey(), entry.getValue());
       continuingRequest.setAttribute(entry.getKey().toString(), value);
@@ -326,10 +328,13 @@ public class ServletScopes {
 
     // Copy the seed values into our local scope map.
     final Context context = new Context();
-    for (Map.Entry<Key<?>, Object> entry : seedMap.entrySet()) {
-      Object value = validateAndCanonicalizeValue(entry.getKey(), entry.getValue());
-      context.map.put(entry.getKey(), value);
-    }
+    Map<Key<?>, Object> validatedAndCanonicalizedMap =
+        Maps.transformEntries(seedMap, new EntryTransformer<Key<?>, Object, Object>() {
+          @Override public Object transformEntry(Key<?> key, Object value) {
+            return validateAndCanonicalizeValue(key, value);
+          }
+        });
+    context.map.putAll(validatedAndCanonicalizedMap);
 
     return new Callable<T>() {
       public T call() throws Exception {
diff --git a/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java b/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
index d8bac74..169dd89 100644
--- a/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
+++ b/extensions/servlet/src/com/google/inject/servlet/UriPatternMatcher.java
@@ -22,7 +22,7 @@ package com.google.inject.servlet;
  *
  * @author dhanji at gmail.com (Dhanji R. Prasanna)
  */
-interface UriPatternMatcher {
+public interface UriPatternMatcher {
   /**
    * @param uri A "contextual" (i.e. relative) Request URI, *not* a complete one.
    * @return Returns true if the uri matches the pattern.
diff --git a/extensions/servlet/test/com/google/inject/servlet/ServletTest.java b/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
index ae1750b..beb0873 100644
--- a/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
+++ b/extensions/servlet/test/com/google/inject/servlet/ServletTest.java
@@ -16,6 +16,7 @@
 
 package com.google.inject.servlet;
 
+import static com.google.inject.Asserts.assertContains;
 import static com.google.inject.Asserts.reserialize;
 import static com.google.inject.servlet.ServletTestUtils.newFakeHttpServletRequest;
 import static com.google.inject.servlet.ServletTestUtils.newFakeHttpServletResponse;
@@ -35,6 +36,11 @@ import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.ProvisionException;
+import com.google.inject.internal.Errors;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
 import com.google.inject.servlet.ServletScopes.NullObject;
 import com.google.inject.util.Providers;
 
@@ -68,7 +74,6 @@ public class ServletTest extends TestCase {
   private static final Key<Map<String, String[]>> REQ_PARAMS_KEY
       = new Key<Map<String, String[]>>(RequestParameters.class) {};
 
-  private static final Key<InRequest> IN_REQUEST_KEY = Key.get(InRequest.class);
   private static final Key<InRequest> IN_REQUEST_NULL_KEY = Key.get(InRequest.class, Null.class);
   private static final Key<InSession> IN_SESSION_KEY = Key.get(InSession.class);
   private static final Key<InSession> IN_SESSION_NULL_KEY = Key.get(InSession.class, Null.class);
@@ -78,6 +83,39 @@ public class ServletTest extends TestCase {
     //we need to clear the reference to the pipeline every test =(
     GuiceFilter.reset();
   }
+  
+  public void testScopeExceptions() throws Exception {
+    Injector injector = Guice.createInjector(new AbstractModule() {
+      @Override protected void configure() {
+        install(new ServletModule());        
+      }
+      @Provides @RequestScoped String provideString() { return "foo"; }
+      @Provides @SessionScoped Integer provideInteger() { return 1; }
+      @Provides @RequestScoped @Named("foo") String provideNamedString() { return "foo"; }
+    });
+    
+    try {
+      injector.getInstance(String.class);
+      fail();
+    } catch(ProvisionException oose) {
+      assertContains(oose.getMessage(), "Cannot access scoped [java.lang.String].");
+    }
+    
+    try {
+      injector.getInstance(Integer.class);
+      fail();
+    } catch(ProvisionException oose) {
+      assertContains(oose.getMessage(), "Cannot access scoped [java.lang.Integer].");
+    }
+    
+    Key<?> key = Key.get(String.class, Names.named("foo"));
+    try {
+      injector.getInstance(key);
+      fail();
+    } catch(ProvisionException oose) {
+      assertContains(oose.getMessage(), "Cannot access scoped [" + Errors.convert(key) + "]");
+    }
+  }
 
   public void testRequestAndResponseBindings() throws Exception {
     final Injector injector = createInjector();
@@ -183,7 +221,7 @@ public class ServletTest extends TestCase {
   public void testRequestAndResponseBindings_matchesPassedParameters() throws Exception {
     final int[] filterInvoked = new int[1];
     final boolean[] servletInvoked = new boolean[1];
-    final Injector injector = createInjector(new ServletModule() {
+    createInjector(new ServletModule() {
       @Override protected void configureServlets() {
         final HttpServletRequest[] previousReq = new HttpServletRequest[1];
         final HttpServletResponse[] previousResp = new HttpServletResponse[1];
@@ -340,8 +378,7 @@ public class ServletTest extends TestCase {
     assertTrue(invoked[0]);
   }
 
-  public void testHttpSessionIsSerializable()
-      throws IOException, ClassNotFoundException, ServletException {
+  public void testHttpSessionIsSerializable() throws Exception {
     final Injector injector = createInjector();
     final HttpServletRequest request = newFakeHttpServletRequest();
     final HttpSession session = request.getSession();
diff --git a/extensions/spring/.gitignore b/extensions/spring/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/spring/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/spring/build.xml b/extensions/spring/build.xml
index 3051929..2d708a6 100644
--- a/extensions/spring/build.xml
+++ b/extensions/spring/build.xml
@@ -13,7 +13,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/spring/pom.xml b/extensions/spring/pom.xml
index 84d9a2d..3c87bf4 100644
--- a/extensions/spring/pom.xml
+++ b/extensions/spring/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-spring</artifactId>
diff --git a/extensions/struts2/.gitignore b/extensions/struts2/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/struts2/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/struts2/build.xml b/extensions/struts2/build.xml
index 6463274..e105372 100644
--- a/extensions/struts2/build.xml
+++ b/extensions/struts2/build.xml
@@ -14,7 +14,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/struts2/pom.xml b/extensions/struts2/pom.xml
index c3156c1..9ed6a01 100644
--- a/extensions/struts2/pom.xml
+++ b/extensions/struts2/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-struts2</artifactId>
diff --git a/extensions/throwingproviders/.gitignore b/extensions/throwingproviders/.gitignore
new file mode 100644
index 0000000..84c048a
--- /dev/null
+++ b/extensions/throwingproviders/.gitignore
@@ -0,0 +1 @@
+/build/
diff --git a/extensions/throwingproviders/build.xml b/extensions/throwingproviders/build.xml
index 27c20e0..d123cf6 100644
--- a/extensions/throwingproviders/build.xml
+++ b/extensions/throwingproviders/build.xml
@@ -13,7 +13,7 @@
   <target name="jar" depends="compile, manifest" description="Build jar.">
     <jar destfile="${build.dir}/${ant.project.name}-${version}.jar"
         manifest="${build.dir}/META-INF/MANIFEST.MF">
-      <fileset dir="${build.dir}/classes"/>
+      <fileset dir="${build.dir}/classes" />
     </jar>
   </target>
 
diff --git a/extensions/throwingproviders/pom.xml b/extensions/throwingproviders/pom.xml
index f1f6878..ec32e80 100644
--- a/extensions/throwingproviders/pom.xml
+++ b/extensions/throwingproviders/pom.xml
@@ -6,11 +6,23 @@
   <parent>
     <groupId>org.sonatype.sisu.inject</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.10</version>
+    <version>3.2.0</version>
   </parent>
 
   <artifactId>guice-throwingproviders</artifactId>
 
   <name>Sisu Guice - Extensions - ThrowingProviders</name>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>**/TestScope*</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/guice.iml b/guice.iml
index cd75c94..118fde8 100644
--- a/guice.iml
+++ b/guice.iml
@@ -90,7 +90,7 @@
     <orderEntry type="module-library" exported="">
       <library>
         <CLASSES>
-          <root url="jar://$MODULE_DIR$/lib/guava-11.0.2.jar!/" />
+          <root url="jar://$MODULE_DIR$/lib/guava-16.0.1.jar!/" />
         </CLASSES>
         <JAVADOC />
         <SOURCES />
diff --git a/pom.xml b/pom.xml
index 6c62b1f..9b4ac4a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,12 +27,12 @@ See the Apache License Version 2.0 for the specific language governing permissio
 
   <groupId>org.sonatype.sisu.inject</groupId>
   <artifactId>guice-parent</artifactId>
-  <version>3.1.10</version>
+  <version>3.2.0</version>
 
   <name>Sisu Guice</name>
 
   <description>
-    Patched build of Guice: a lightweight dependency injection framework for Java 5 and above
+    Patched build of Guice: a lightweight dependency injection framework for Java 6 and above
   </description>
 
   <url>http://code.google.com/p/google-guice/</url>
@@ -64,6 +64,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
     <connection>scm:git:git at github.com:sonatype/sisu-guice.git</connection>
     <developerConnection>scm:git:git at github.com:sonatype/sisu-guice.git</developerConnection>
     <url>http://github.com/sonatype/sisu-guice</url>
+    <tag>sisu-guice-3.2.0</tag>
   </scm>
 
   <issueManagement>
@@ -110,14 +111,10 @@ See the Apache License Version 2.0 for the specific language governing permissio
   </properties>
 
   <dependencies>
-    <!--
-     | Run tests with TestNG
-    -->
     <dependency>
-      <groupId>org.testng</groupId>
-      <artifactId>testng</artifactId>
-      <version>5.11</version>
-      <classifier>jdk15</classifier>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.11</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
@@ -168,26 +165,30 @@ See the Apache License Version 2.0 for the specific language governing permissio
           </executions>
         </plugin>
         <!--
-         | Make sure we only use Java5 methods
+         | Make sure we only use Java6 methods
         -->
         <plugin>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>2.3.2</version>
+          <configuration>
+            <source>1.6</source>
+            <target>1.6</target>
+          </configuration>
         </plugin>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>animal-sniffer-maven-plugin</artifactId>
-          <version>1.6</version>
+          <version>1.10</version>
           <configuration>
             <signature>
               <groupId>org.codehaus.mojo.signature</groupId>
-              <artifactId>java15</artifactId>
+              <artifactId>java16</artifactId>
               <version>1.0</version>
             </signature>
           </configuration>
           <executions>
             <execution>
-              <id>check-java-1.5-compat</id>
+              <id>check-java-1.6-compat</id>
               <phase>process-classes</phase>
               <goals>
                 <goal>check</goal>
@@ -244,10 +245,8 @@ See the Apache License Version 2.0 for the specific language governing permissio
               <Bundle-DocURL>http://code.google.com/p/google-guice/</Bundle-DocURL>
               <Bundle-Name>${project.artifactId}</Bundle-Name>
               <Bundle-Vendor>Sonatype, Inc.</Bundle-Vendor>
-              <Bundle-RequiredExecutionEnvironment>
-                J2SE-1.5,JavaSE-1.6
-              </Bundle-RequiredExecutionEnvironment>
-              <Import-Package>!com.google.inject.*,*</Import-Package>
+              <Bundle-RequiredExecutionEnvironment>JavaSE-1.6</Bundle-RequiredExecutionEnvironment>
+              <Import-Package>!net.sf.cglib.*,!org.objectweb.asm.*,!com.google.inject.*,*</Import-Package>
               <_exportcontents>!*.internal.*,$(module).*;version=${guice.api.version}</_exportcontents>
               <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
               <_nouses>true</_nouses>
@@ -297,7 +296,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
         </plugin>
         <plugin>
           <artifactId>maven-javadoc-plugin</artifactId>
-          <version>2.7</version>
+          <version>2.9.1</version>
           <configuration>
             <doclet>com.google.doclava.Doclava</doclet>
             <docletPath>
@@ -305,9 +304,19 @@ See the Apache License Version 2.0 for the specific language governing permissio
               ${project.basedir}/../../lib/build/doclava.jar
             </docletPath>
             <!--
-             | bootclasspath required by Sun's JVM 
+             | bootclasspath required by Sun's JVM
             -->
             <bootclasspath>${sun.boot.class.path}</bootclasspath>
+            <!--
+             | javadoc requires @javax.annotation.Nullable
+            -->
+            <additionalDependencies>
+              <additionalDependency>
+                <groupId>com.google.code.findbugs</groupId>
+                <artifactId>jsr305</artifactId>
+                <version>2.0.3</version>
+              </additionalDependency>
+            </additionalDependencies>
             <excludePackageNames>*.internal</excludePackageNames>
             <additionalparam>
               -quiet
@@ -337,7 +346,7 @@ See the Apache License Version 2.0 for the specific language governing permissio
         </plugin>
         <plugin>
           <artifactId>maven-release-plugin</artifactId>
-          <version>2.2.1</version>
+          <version>2.5</version>
           <configuration>
             <autoVersionSubmodules>true</autoVersionSubmodules>
           </configuration>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/sisu-guice.git



More information about the pkg-java-commits mailing list