Merge pull request #839 from magnayn/master

Allow JPA properties to be Objects as well as simple strings.
diff --git a/README.md b/README.md
index 2a54be0..c71ee05 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 Guice
 ====
 
-**Now, out in [4.0 Beta4](https://github.com/google/guice/wiki/Guice40)!**
+**Now, out in [4.0 Beta5](https://github.com/google/guice/wiki/Guice40)!**
 
 **Documentation:** [User Guide](https://github.com/google/guice/wiki/Motivation), [3.0 javadocs](http://google.github.io/guice/api-docs/3.0/javadoc/packages.html), [Latest javadocs](http://google.github.io/guice/api-docs/latest/javadoc/index.html) <br/>
 **Continuous Integration:** [![Build Status](https://api.travis-ci.org/google/guice.png?branch=master)](https://travis-ci.org/google/guice) <br
diff --git a/core/pom.xml b/core/pom.xml
index 33e6dcc..4b99d09 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -17,49 +17,39 @@
     <dependency>
       <groupId>javax.inject</groupId>
       <artifactId>javax.inject</artifactId>
-      <version>1</version>
     </dependency>
     <dependency>
       <groupId>aopalliance</groupId>
       <artifactId>aopalliance</artifactId>
-      <version>1.0</version>
     </dependency>
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
-      <version>16.0.1</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava-testlib</artifactId>
-      <version>16.0.1</version>
-      <scope>test</scope>
     </dependency>
     <!--
      | CGLIB is embedded by default by the JarJar build profile
     -->
     <dependency>
-      <groupId>cglib</groupId>
-      <artifactId>cglib</artifactId>
-      <version>3.1</version>
-      <exclusions>
-        <exclusion>
-          <groupId>asm</groupId>
-          <artifactId>asm</artifactId>
-        </exclusion>
-      </exclusions>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm</artifactId>
       <optional>true</optional>
     </dependency>
     <dependency>
-      <groupId>org.ow2.asm</groupId>
-      <artifactId>asm</artifactId>
-      <version>5.0.3</version>
+      <groupId>cglib</groupId>
+      <artifactId>cglib</artifactId>
       <optional>true</optional>
     </dependency>
+    <!--
+     | Test dependencies
+    -->
     <dependency>
       <groupId>javax.inject</groupId>
       <artifactId>javax.inject-tck</artifactId>
-      <version>1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-testlib</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -91,7 +81,7 @@
         <artifactId>maven-remote-resources-plugin</artifactId>
       </plugin>
       <!--
-       | Enable Java5 conformance checks
+       | Enable Java6 conformance checks
       -->
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
@@ -121,6 +111,7 @@
         <configuration>
           <instructions>
             <Bundle-Name>${project.artifactId}$(if;$(classes;NAMED;*.MethodAspect);; (no_aop))</Bundle-Name>
+            <Import-Package>!net.sf.cglib.*,!org.objectweb.asm.*,!com.google.inject.*,*</Import-Package>
             <Eclipse-ExtensibleAPI>true</Eclipse-ExtensibleAPI>
           </instructions>
         </configuration>
@@ -235,7 +226,7 @@
           <plugin>
             <groupId>org.sonatype.plugins</groupId>
             <artifactId>jarjar-maven-plugin</artifactId>
-            <version>1.8</version>
+            <version>1.9</version>
             <executions>
               <execution>
                 <id>jarjar</id>
@@ -276,22 +267,25 @@
           </plugin>
           <plugin>
             <!--
-             | Package the original non-JarJar'd classes so extensions can compile against them
+             | Attach the original non-JarJar'd classes so extensions can compile against them
             -->
-            <artifactId>maven-jar-plugin</artifactId>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>build-helper-maven-plugin</artifactId>
+            <version>1.8</version>
             <executions>
               <execution>
                 <id>classes</id>
                 <phase>package</phase>
                 <goals>
-                  <goal>jar</goal>
+                  <goal>attach-artifact</goal>
                 </goals>
                 <configuration>
-                  <classesDirectory>${project.build.directory}/original-classes</classesDirectory>
-                  <classifier>classes</classifier>
-                  <archive>
-                    <manifestFile combine.self="override" />
-                  </archive>
+                  <artifacts>
+                    <artifact>
+                      <file>${project.build.directory}/original-${project.build.finalName}.jar</file>
+                      <classifier>classes</classifier>
+                    </artifact>
+                  </artifacts>
                 </configuration>
               </execution>
             </executions>
diff --git a/core/src/com/google/inject/internal/DelayedInitialize.java b/core/src/com/google/inject/internal/DelayedInitialize.java
index 80e52d1..82a8463 100644
--- a/core/src/com/google/inject/internal/DelayedInitialize.java
+++ b/core/src/com/google/inject/internal/DelayedInitialize.java
@@ -1,4 +1,18 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/**
+ * Copyright (C) 2011 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;
 
diff --git a/core/src/com/google/inject/internal/InternalFlags.java b/core/src/com/google/inject/internal/InternalFlags.java
index 2c4ed75..2b3c3a6 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/Nullability.java b/core/src/com/google/inject/internal/Nullability.java
index f90342e..76f7e76 100644
--- a/core/src/com/google/inject/internal/Nullability.java
+++ b/core/src/com/google/inject/internal/Nullability.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (C) 2010 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.lang.annotation.Annotation;
diff --git a/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java b/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
index da6229e..f254b41 100644
--- a/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
+++ b/core/src/com/google/inject/internal/ProviderInstanceBindingImpl.java
@@ -1,18 +1,18 @@
-/*
-Copyright (C) 2007 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.
-*/
+/**
+ * Copyright (C) 2007 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;
 
diff --git a/core/src/com/google/inject/internal/ProviderMethodsModule.java b/core/src/com/google/inject/internal/ProviderMethodsModule.java
index 1074bd2..214039d 100644
--- a/core/src/com/google/inject/internal/ProviderMethodsModule.java
+++ b/core/src/com/google/inject/internal/ProviderMethodsModule.java
@@ -48,6 +48,8 @@
  * @author jessewilson@google.com (Jesse Wilson)
  */
 public final class ProviderMethodsModule implements Module {
+  private static final Key<Logger> LOGGER_KEY = Key.get(Logger.class);
+
   private final Object delegate;
   private final TypeLiteral<?> typeLiteral;
   private final boolean skipFastClassGeneration;
@@ -206,7 +208,7 @@
     Annotation[][] parameterAnnotations = method.getParameterAnnotations();
     for (int i = 0; i < parameterTypes.size(); i++) {
       Key<?> key = getKey(errors, parameterTypes.get(i), method, parameterAnnotations[i]);
-      if(key.equals(Key.get(Logger.class))) {
+      if (key.equals(LOGGER_KEY)) {
         // If it was a Logger, change the key to be unique & bind it to a
         // provider that provides a logger with a proper name.
         // This solves issue 482 (returning a new anonymous logger on every call exhausts memory)
diff --git a/core/src/com/google/inject/internal/ScopeBindingProcessor.java b/core/src/com/google/inject/internal/ScopeBindingProcessor.java
index 5d49de3..3e68b30 100644
--- a/core/src/com/google/inject/internal/ScopeBindingProcessor.java
+++ b/core/src/com/google/inject/internal/ScopeBindingProcessor.java
@@ -36,8 +36,8 @@
   }
 
   @Override public Boolean visit(ScopeBinding command) {
-    Scope scope = command.getScope();
-    Class<? extends Annotation> annotationType = command.getAnnotationType();
+    Scope scope = checkNotNull(command.getScope(), "scope");
+    Class<? extends Annotation> annotationType = checkNotNull(command.getAnnotationType(), "annotation type");
 
     if (!Annotations.isScopeAnnotation(annotationType)) {
       errors.missingScopeAnnotation(annotationType);
@@ -49,11 +49,12 @@
       // Go ahead and bind anyway so we don't get collateral errors.
     }
 
-    ScopeBinding existing = injector.state.getScopeBinding(checkNotNull(annotationType, "annotation type"));
+    ScopeBinding existing = injector.state.getScopeBinding(annotationType);
     if (existing != null) {
-      errors.duplicateScopes(existing, annotationType, scope);
+      if (!scope.equals(existing.getScope())) {
+        errors.duplicateScopes(existing, annotationType, scope);
+      }
     } else {
-      checkNotNull(scope, "scope");
       injector.state.putScopeBinding(annotationType, command);
     }
 
diff --git a/core/src/com/google/inject/internal/WeakKeySet.java b/core/src/com/google/inject/internal/WeakKeySet.java
index 0741cd2..ca137df 100644
--- a/core/src/com/google/inject/internal/WeakKeySet.java
+++ b/core/src/com/google/inject/internal/WeakKeySet.java
@@ -30,7 +30,6 @@
 import com.google.inject.Key;
 import com.google.inject.internal.util.SourceProvider;
 
-import java.lang.annotation.Annotation;
 import java.util.Map;
 import java.util.Set;
 
@@ -42,7 +41,7 @@
 final class WeakKeySet {
 
   private Map<Key<?>, Multiset<Object>> backingMap;
-  
+
   /**
    * This is already locked externally on add and getSources but we need it to handle clean up in
    * the evictionCache's RemovalListener.
@@ -155,14 +154,4 @@
           && Objects.equal(source, other.source);
     }
   }
-
-  /**
-   * Returns {@code true} if the {@link Key} represents a multibound element.
-   */
-  private static boolean isMultiBinderKey(Key<?> key) {
-    Annotation annotation = key.getAnnotation();
-    return annotation != null
-        // Can't depend on multibinder in core.
-        && "com.google.inject.multibindings.RealElement".equals(annotation.getClass().getName());
-  }
 }
diff --git a/core/src/com/google/inject/spi/ElementSource.java b/core/src/com/google/inject/spi/ElementSource.java
index 3c1837c..8414b21 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/ProvidesMethodBinding.java b/core/src/com/google/inject/spi/ProvidesMethodBinding.java
index f35d9a4..010e936 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) 2014 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..62c8721 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) 2014 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/core/src/com/google/inject/spi/Toolable.java b/core/src/com/google/inject/spi/Toolable.java
index 37ed41f..ffabd9d 100644
--- a/core/src/com/google/inject/spi/Toolable.java
+++ b/core/src/com/google/inject/spi/Toolable.java
@@ -1,3 +1,19 @@
+/**
+ * Copyright (C) 2010 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 static java.lang.annotation.ElementType.METHOD;
diff --git a/core/test/com/google/inject/ScopesTest.java b/core/test/com/google/inject/ScopesTest.java
index d95c797..557df0c 100644
--- a/core/test/com/google/inject/ScopesTest.java
+++ b/core/test/com/google/inject/ScopesTest.java
@@ -338,6 +338,19 @@
     }
   }
 
+  public void testBindDuplicateScope() {
+    Injector injector = Guice.createInjector(new AbstractModule() {
+      @Override protected void configure() {
+        bindScope(CustomScoped.class, Scopes.SINGLETON);
+        bindScope(CustomScoped.class, Scopes.SINGLETON);
+      }
+    });
+
+    assertSame(
+        injector.getInstance(AnnotatedCustomScoped.class),
+        injector.getInstance(AnnotatedCustomScoped.class));
+  }
+
   public void testDuplicateScopeAnnotations() {
     Injector injector = Guice.createInjector(new AbstractModule() {
       @Override protected void configure() {
diff --git a/extensions/mini/pom.xml b/extensions/mini/pom.xml
index 03f5c01..fdaa91d 100644
--- a/extensions/mini/pom.xml
+++ b/extensions/mini/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.0-SNAPSHOT</version>
+    <version>4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>guice-mini</artifactId>
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Indexer.java b/extensions/multibindings/src/com/google/inject/multibindings/Indexer.java
index d233be6..4edcf76 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/Indexer.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/Indexer.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2914 Google Inc.
+ * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
index 68610a3..4e5ec78 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/MapBinder.java
@@ -539,15 +539,19 @@
       }
 
       @Override public Map<K, V> get() {
-        Map<K, V> map = new LinkedHashMap<K, V>();
-        for (Entry<K, Provider<V>> entry : mapProvider.get().entrySet()) {
-          V value = entry.getValue().get();
-          K key = entry.getKey();
+        // We can initialize the internal table efficiently this way and then swap the values
+        // one by one.
+        Map<K, Object> map = new LinkedHashMap<K, Object>(mapProvider.get());
+        for (Entry<K, Object> entry : map.entrySet()) {
+          @SuppressWarnings("unchecked")  // we initialized the entries with providers
+          V value = ((Provider<V>) entry.getValue()).get();
           checkConfiguration(value != null,
-              "Map injection failed due to null value for key \"%s\"", key);
-          map.put(key, value);
+              "Map injection failed due to null value for key \"%s\"", entry.getKey());
+          entry.setValue(value);
         }
-        return Collections.unmodifiableMap(map);
+        @SuppressWarnings("unchecked")  // if we exited the loop then we replaced all Providers
+        Map<K, V> typedMap = (Map<K, V>) map;
+        return Collections.unmodifiableMap(typedMap);
       }
 
       @Override public Set<Dependency<?>> getDependencies() {
diff --git a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
index 98db1e4..50ce9c1 100644
--- a/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
+++ b/extensions/multibindings/src/com/google/inject/multibindings/Multibinder.java
@@ -17,6 +17,7 @@
 package com.google.inject.multibindings;
 
 import static com.google.common.base.Predicates.equalTo;
+import static com.google.common.primitives.Ints.MAX_POWER_OF_TWO;
 import static com.google.common.collect.Iterables.filter;
 import static com.google.common.collect.Iterables.getOnlyElement;
 import static com.google.inject.multibindings.Element.Type.MULTIBINDER;
@@ -315,6 +316,16 @@
       this.binder = null;
     }
 
+    // This is forked from com.google.common.collect.Maps.capacity 
+    private static int mapCapacity(int numBindings) {
+      if (numBindings < 3) {
+        return numBindings + 1;
+      } else  if (numBindings < MAX_POWER_OF_TWO) {
+        return (int) (numBindings / 0.75F + 1.0F);
+      }
+      return Integer.MAX_VALUE;
+    }
+
     boolean permitsDuplicates(Injector injector) {
       return injector.getBindings().containsKey(permitDuplicatesKey);
     }
@@ -333,7 +344,7 @@
     public Set<T> get() {
       checkConfiguration(isInitialized(), "Multibinder is not initialized");
 
-      Map<T, Binding<T>> result = new LinkedHashMap<T, Binding<T>>();
+      Map<T, Binding<T>> result = new LinkedHashMap<T, Binding<T>>(mapCapacity(bindings.size()));
       for (Binding<T> binding : bindings) {
         final T newValue = binding.getProvider().get();
         checkConfiguration(newValue != null, "Set injection failed due to null element");
@@ -423,12 +434,13 @@
         implements ProviderWithDependencies<Collection<Provider<T>>> {
       @Override public Collection<Provider<T>> get() {
         checkConfiguration(isInitialized(), "Multibinder is not initialized");
-
-        ImmutableList.Builder<Provider<T>> resultBuilder = new ImmutableList.Builder<Provider<T>>();
-        for (Binding<T> binding : bindings) {
-          resultBuilder.add(binding.getProvider());
+        int size = bindings.size();
+        @SuppressWarnings("unchecked")  // safe because we only put Provider<T> into it.
+        Provider<T>[] providers = new Provider[size];
+        for (int i = 0; i < size; i++) {
+          providers[i] = bindings.get(i).getProvider();
         }
-        return resultBuilder.build();
+        return ImmutableList.copyOf(providers);
       }
 
       @Override public Set<Dependency<?>> getDependencies() {
diff --git a/extensions/multibindings/test/com/google/inject/multibindings/RealElementTest.java b/extensions/multibindings/test/com/google/inject/multibindings/RealElementTest.java
index e56048a..8dabf83 100644
--- a/extensions/multibindings/test/com/google/inject/multibindings/RealElementTest.java
+++ b/extensions/multibindings/test/com/google/inject/multibindings/RealElementTest.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2914 Google Inc.
+ * Copyright (C) 2014 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/extensions/persist/src/com/google/inject/persist/finder/package-info.java b/extensions/persist/src/com/google/inject/persist/finder/package-info.java
index 514a54f..279929c 100644
--- a/extensions/persist/src/com/google/inject/persist/finder/package-info.java
+++ b/extensions/persist/src/com/google/inject/persist/finder/package-info.java
@@ -1,4 +1,20 @@
 /**
+ * Copyright (C) 2010 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.
+ */
+
+/**
  * Dynamic Finder API for Guice Persist.
  */
-package com.google.inject.persist.finder;
\ No newline at end of file
+package com.google.inject.persist.finder;
diff --git a/extensions/persist/src/com/google/inject/persist/jpa/package-info.java b/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
index 7a55893..f9e46da 100644
--- a/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
+++ b/extensions/persist/src/com/google/inject/persist/jpa/package-info.java
@@ -1,4 +1,20 @@
 /**
+ * Copyright (C) 2010 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.
+ */
+
+/**
  * guice-persist's Java Persistence API (JPA) support.
  */
-package com.google.inject.persist.jpa;
\ No newline at end of file
+package com.google.inject.persist.jpa;
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 9391b9d..084967c 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -62,7 +62,6 @@
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava-testlib</artifactId>
-      <version>16.0.1</version>
       <scope>test</scope>
     </dependency>
     <!--
@@ -70,21 +69,13 @@
      | in an execution that doesn't include package.
     -->
     <dependency>
-      <groupId>cglib</groupId>
-      <artifactId>cglib</artifactId>
-      <version>3.1</version>
-      <scope>test</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>asm</groupId>
-          <artifactId>asm</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
       <groupId>org.ow2.asm</groupId>
       <artifactId>asm</artifactId>
-      <version>5.0.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>cglib</groupId>
+      <artifactId>cglib</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
@@ -98,7 +89,7 @@
         <artifactId>maven-remote-resources-plugin</artifactId>
       </plugin>
       <!--
-       | Enable Java5 conformance checks
+       | Enable Java6 conformance checks
       -->
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
diff --git a/extensions/service/pom.xml b/extensions/service/pom.xml
index 8dd4001..2d96e0d 100644
--- a/extensions/service/pom.xml
+++ b/extensions/service/pom.xml
@@ -6,7 +6,7 @@
   <parent>
     <groupId>com.google.inject.extensions</groupId>
     <artifactId>extensions-parent</artifactId>
-    <version>3.1.0-SNAPSHOT</version>
+    <version>4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>guice-service</artifactId>
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
index 0352b9c..25020ca 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java
@@ -44,12 +44,6 @@
 
   private ServletScopes() {}
 
-  /** Keys bound in request-scope which are handled directly by GuiceFilter. */
-  private static final ImmutableSet<Key<?>> REQUEST_CONTEXT_KEYS = ImmutableSet.of(
-      Key.get(HttpServletRequest.class),
-      Key.get(HttpServletResponse.class),
-      new Key<Map<String, String[]>>(RequestParameters.class) {});
-
   /**
    * A threadlocal scope map for non-http request scopes. The {@link #REQUEST}
    * scope falls back to this scope map if no http request is available, and
@@ -67,6 +61,13 @@
   public static final Scope REQUEST = new Scope() {
     public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
       return new Provider<T>() {
+
+        /** Keys bound in request-scope which are handled directly by GuiceFilter. */
+        private final ImmutableSet<Key<?>> REQUEST_CONTEXT_KEYS = ImmutableSet.of(
+                Key.get(HttpServletRequest.class),
+                Key.get(HttpServletResponse.class),
+                new Key<Map<String, String[]>>(RequestParameters.class) {});
+
         public T get() {
           // Check if the alternate request scope should be used, if no HTTP
           // request is in progress.
diff --git a/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java b/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java
index 6a29425..88ecd31 100644
--- a/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java
+++ b/extensions/servlet/src/com/google/inject/servlet/ServletUtils.java
@@ -1,4 +1,18 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
+/**
+ * Copyright (C) 2012 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;
 
diff --git a/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java b/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java
index 948b711..6c75fc7 100644
--- a/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java
+++ b/extensions/testlib/src/com/google/inject/testing/fieldbinder/Bind.java
@@ -37,4 +37,12 @@
    * rather than to the field's actual type.
    */
   Class<?> to() default Bind.class;
+
+  /**
+   * If true, {@link BoundFieldModule} will delay retrieving the field's value until injection time
+   * rather than eagerly fetching it at configure time.
+   * 
+   * <p>This option is not supported with Provider valued fields.
+   */
+  boolean lazy() default false;
 }
diff --git a/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java b/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java
index 7943e89..c280848 100644
--- a/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java
+++ b/extensions/testlib/src/com/google/inject/testing/fieldbinder/BoundFieldModule.java
@@ -71,6 +71,9 @@
  * public class TestFoo {
  *   // bind(new TypeLiteral{@code <List<Object>>}() {}).toInstance(listOfObjects);
  *   {@literal @}Bind private List{@code <Object>} listOfObjects = Lists.of();
+ *   
+ *   // bind(String.class).toProvider(new Provider() { public String get() { return userName; }});
+ *   {@literal @}Bind(lazy = true) private String userName;
  *
  *   // bind(SuperClass.class).toInstance(aSubClass);
  *   {@literal @}Bind(to = SuperClass.class) private SubClass aSubClass = new SubClass();
@@ -113,8 +116,11 @@
   }
 
   private static class BoundFieldException extends RuntimeException {
-    BoundFieldException(String message) {
-      super(message);
+    private final Message message;
+
+    BoundFieldException(Message message) {
+      super(message.getMessage());
+      this.message = message;
     }
   }
 
@@ -148,7 +154,7 @@
      * {@link Number}, and {@code @Bind(to = Object.class) Provider<Number> one = new Integer(1);}
      * will be {@link Number}.
      *
-     * @see getNaturalFieldType
+     * @see #getNaturalFieldType
      */
     final Optional<TypeLiteral<?>> naturalType;
 
@@ -173,7 +179,7 @@
       if (bindClass == Bind.class) {
         Preconditions.checkState(naturalType != null);
         if (!this.naturalType.isPresent()) {
-          addErrorAndThrow(
+          throwBoundFieldException(
               field,
               "Non parameterized Provider fields must have an explicit "
               + "binding class via @Bind(to = Foo.class)");
@@ -240,7 +246,7 @@
       return Optional.absent();
     }
     if (hasInject(field)) {
-      addErrorAndThrow(
+      throwBoundFieldException(
           field,
           "Fields annotated with both @Bind and @Inject are illegal.");
     }
@@ -282,12 +288,12 @@
     return com.google.inject.Provider.class == clazz || javax.inject.Provider.class == clazz;
   }
 
-  private void bindField(BoundFieldInfo fieldInfo) {
+  private void bindField(final BoundFieldInfo fieldInfo) {
     if (fieldInfo.naturalType.isPresent()) {
       Class<?> naturalRawType = fieldInfo.naturalType.get().getRawType();
       Class<?> boundRawType = fieldInfo.boundType.getRawType();
       if (!boundRawType.isAssignableFrom(naturalRawType)) {
-        addErrorAndThrow(
+        throwBoundFieldException(
             fieldInfo.field,
             "Requested binding type \"%s\" is not assignable from field binding type \"%s\"",
             boundRawType.getName(),
@@ -307,37 +313,46 @@
     @SuppressWarnings("unchecked")
     AnnotatedBindingBuilder<Object> binderUnsafe = (AnnotatedBindingBuilder<Object>) binder;
 
-    Object fieldValue = fieldInfo.getValue();
-
-    if (fieldValue == null) {
-      addErrorAndThrow(
-          fieldInfo.field,
-          "Binding to null values is not allowed. "
-          + "Use Providers.of(null) if this is your intended behavior.",
-          fieldInfo.field.getName());
-    }
-
     if (isTransparentProvider(fieldInfo.type.getRawType())) {
+      if (fieldInfo.bindAnnotation.lazy()) {
+        // We don't support this because it is confusing about when values are captured.
+        throwBoundFieldException(fieldInfo.field, 
+            "'lazy' is incompatible with Provider valued fields");
+      }
       // This is safe because we checked that the field's type is Provider above.
       @SuppressWarnings("unchecked")
-      Provider<?> fieldValueUnsafe = (Provider<?>) fieldValue;
-
+      Provider<?> fieldValueUnsafe = (Provider<?>) getFieldValue(fieldInfo);
       binderUnsafe.toProvider(fieldValueUnsafe);
+    } else if (fieldInfo.bindAnnotation.lazy()) {
+      binderUnsafe.toProvider(new Provider<Object>() {
+        @Override public Object get() {
+          return getFieldValue(fieldInfo);
+        }
+      });
     } else {
-      binderUnsafe.toInstance(fieldValue);
+      binderUnsafe.toInstance(getFieldValue(fieldInfo));
     }
   }
 
-  private void addErrorAndThrow(Field field, String format, Object... args) {
+  private Object getFieldValue(final BoundFieldInfo fieldInfo) {
+    Object fieldValue = fieldInfo.getValue();
+    if (fieldValue == null) {
+      throwBoundFieldException(
+          fieldInfo.field,
+          "Binding to null values is not allowed. "
+              + "Use Providers.of(null) if this is your intended behavior.",
+              fieldInfo.field.getName());
+    }
+    return fieldValue;
+  }
+
+  private void throwBoundFieldException(Field field, String format, Object... args) {
     Preconditions.checkNotNull(binder);
     String source = String.format(
         "%s field %s",
         field.getDeclaringClass().getName(),
         field.getName());
-    Message messageObj = new Message(source, String.format(format, args));
-
-    binder.addError(messageObj);
-    throw new BoundFieldException(messageObj.getMessage());
+    throw new BoundFieldException(new Message(source, String.format(format, args)));
   }
 
   @Override
@@ -355,7 +370,8 @@
             bindField(fieldInfoOpt.get());
           }
         } catch (BoundFieldException e) {
-          // addErrorAndThrow already called addError, so do nothing
+          // keep going to try to collect as many errors as possible
+          binder.addError(e.message);
         }
       }
       currentClassType =
diff --git a/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java b/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java
index 768bf3e..2db1215 100644
--- a/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java
+++ b/extensions/testlib/test/com/google/inject/testing/fieldbinder/BoundFieldModuleTest.java
@@ -27,8 +27,10 @@
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Provider;
+import com.google.inject.ProvisionException;
 import com.google.inject.name.Named;
 import com.google.inject.name.Names;
+import com.google.inject.util.Providers;
 
 import junit.framework.TestCase;
 
@@ -686,4 +688,45 @@
     assertEquals(testValue1, injector.getInstance(Integer.class));
     assertEquals(testValue2, injector.getInstance(Number.class));
   }
+
+  static final class LazyClass {
+    @Bind(lazy = true) Integer foo = 1;
+  }
+
+  public void testFieldBound_lazy() {
+    LazyClass asProvider = new LazyClass();
+    Injector injector = Guice.createInjector(BoundFieldModule.of(asProvider));
+    assertEquals(1, injector.getInstance(Integer.class).intValue());
+    asProvider.foo++;
+    assertEquals(2, injector.getInstance(Integer.class).intValue());
+  }
+
+  public void testFieldBound_lazy_rejectNull() {
+    LazyClass asProvider = new LazyClass();
+    Injector injector = Guice.createInjector(BoundFieldModule.of(asProvider));
+    assertEquals(1, injector.getInstance(Integer.class).intValue());
+    asProvider.foo = null;
+    try {
+      injector.getInstance(Integer.class);
+      fail();
+    } catch (ProvisionException e) {
+      assertContains(e.getMessage(),
+          "Binding to null values is not allowed. "
+          + "Use Providers.of(null) if this is your intended behavior.");
+    }
+  }
+
+  static final class LazyProviderClass {
+    @Bind(lazy = true) Provider<Integer> foo = Providers.of(null);
+  }
+
+  public void testFieldBoundAsProvider_rejectProvider() {
+    LazyProviderClass asProvider = new LazyProviderClass();
+    try {
+      Guice.createInjector(BoundFieldModule.of(asProvider));
+      fail();
+    } catch (CreationException e) {
+      assertContains(e.getMessage(), "'lazy' is incompatible with Provider valued fields");
+    }
+  }
 }
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
index 3d8a001..ca5ab77 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProvideUtils.java
@@ -1,4 +1,18 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
+/**
+ * Copyright (C) 2012 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.throwingproviders;
 
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
index 6c81dab..dce2bfa 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderMethodsModule.java
@@ -45,6 +45,8 @@
  * @author sameb@google.com (Sam Berlin)
  */
 final class CheckedProviderMethodsModule implements Module {
+  private static final Key<Logger> LOGGER_KEY = Key.get(Logger.class);
+
   private final Object delegate;
   private final TypeLiteral<?> typeLiteral;
 
@@ -96,7 +98,7 @@
     Annotation[][] parameterAnnotations = method.getParameterAnnotations();
     for (int i = 0; i < parameterTypes.size(); i++) {
       Key<?> key = getKey(errors, parameterTypes.get(i), method, parameterAnnotations[i]);
-      if(key.equals(Key.get(Logger.class))) {
+      if (key.equals(LOGGER_KEY)) {
         // If it was a Logger, change the key to be unique & bind it to a
         // provider that provides a logger with a proper name.
         // This solves issue 482 (returning a new anonymous logger on every call exhausts memory)
diff --git a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java
index 4b87f40..79df84d 100644
--- a/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java
+++ b/extensions/throwingproviders/src/com/google/inject/throwingproviders/CheckedProviderWithDependencies.java
@@ -1,4 +1,18 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
+/**
+ * Copyright (C) 2012 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.throwingproviders;
 
diff --git a/lib/build/header-definitions.xml b/lib/build/header-definitions.xml
new file mode 100644
index 0000000..84bf786
--- /dev/null
+++ b/lib/build/header-definitions.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<additionalHeaders>
+  <javadoc_style>
+    <firstLine>/**</firstLine>
+    <beforeEachLine> * </beforeEachLine>
+    <endLine> */&#10;</endLine>
+    <!--afterEachLine></afterEachLine-->
+    <!--skipLine></skipLine-->
+    <firstLineDetectionPattern>(\s|\t)*/\*.*$</firstLineDetectionPattern>
+    <lastLineDetectionPattern>.*\*/(\s|\t)*$</lastLineDetectionPattern>
+    <allowBlankLines>false</allowBlankLines>
+    <isMultiline>true</isMultiline>
+    <padLines>false</padLines>
+  </javadoc_style>
+</additionalHeaders>
diff --git a/lib/build/header.txt b/lib/build/header.txt
new file mode 100644
index 0000000..5d6a87e
--- /dev/null
+++ b/lib/build/header.txt
@@ -0,0 +1,13 @@
+Copyright (C) 2014 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.
diff --git a/pom.xml b/pom.xml
index 37305d0..cc93bc7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,10 @@
 
   <distributionManagement>
     <!-- override the parent's directory to point to the canonical place, and use https. -->
+    <repository>
+      <id>google-releases</id>
+      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+    </repository>
     <snapshotRepository>
       <id>google-snapshots</id>
       <url>https://oss.sonatype.org/content/repositories/snapshots</url>
@@ -118,6 +122,46 @@
     <gpg.skip>true</gpg.skip>
   </properties>
 
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>javax.inject</groupId>
+        <artifactId>javax.inject</artifactId>
+        <version>1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.inject</groupId>
+        <artifactId>javax.inject-tck</artifactId>
+        <version>1</version>
+      </dependency>
+      <dependency>
+        <groupId>aopalliance</groupId>
+        <artifactId>aopalliance</artifactId>
+        <version>1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>16.0.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava-testlib</artifactId>
+        <version>16.0.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.ow2.asm</groupId>
+        <artifactId>asm</artifactId>
+        <version>5.0.3</version>
+      </dependency>
+      <dependency>
+        <groupId>cglib</groupId>
+        <artifactId>cglib</artifactId>
+        <version>3.1</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -154,6 +198,37 @@
     <pluginManagement>
       <plugins>
         <!--
+         | Use 'mvn license:format -N' at top of project to add missing headers
+        -->
+        <plugin>
+          <groupId>com.mycila</groupId>
+          <artifactId>license-maven-plugin</artifactId>
+          <version>2.6</version>
+          <configuration>
+            <encoding>UTF-8</encoding>
+            <header>${project.basedir}/lib/build/header.txt</header>
+            <headerDefinitions>
+              <headerDefinition>${project.basedir}/lib/build/header-definitions.xml</headerDefinition>
+            </headerDefinitions>
+            <skipExistingHeaders>true</skipExistingHeaders>
+            <aggregate>true</aggregate>
+            <includes>
+              <include>**/*.java</include>
+            </includes>
+            <excludes>
+              <!-- avoid touching munged/lib/test/example code -->
+              <exclude>**/build/**</exclude>
+              <exclude>**/target/**</exclude>
+              <exclude>**/lib/**</exclude>
+              <exclude>**/test/**</exclude>
+              <exclude>**/example*/**</exclude>
+            </excludes>
+            <mapping>
+              <java>JAVADOC_STYLE</java>
+            </mapping>
+          </configuration>
+        </plugin>
+        <!--
          | Standard LICENSE and NOTICE files
         -->
         <plugin>
@@ -173,7 +248,7 @@
           </executions>
         </plugin>
         <!--
-         | Make sure we only use Java5 methods
+         | Make sure we only use Java6 methods
         -->
         <plugin>
           <artifactId>maven-compiler-plugin</artifactId>
@@ -253,12 +328,10 @@
               <Bundle-DocURL>https://github.com/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>
+              <Bundle-RequiredExecutionEnvironment>JavaSE-1.6</Bundle-RequiredExecutionEnvironment>
               <Import-Package>!com.google.inject.*,*</Import-Package>
               <_exportcontents>!*.internal.*,$(module).*;version=${guice.api.version}</_exportcontents>
-              <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+              <_versionpolicy>$(version;==;$(@))</_versionpolicy>
               <_nouses>true</_nouses>
               <_removeheaders>
                 Embed-Dependency,Embed-Transitive,