diff --git a/core/pom.xml b/core/pom.xml
index f4c4ac8..2035020 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -73,6 +73,12 @@
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
+    <!--  for ohai -->
+    <dependency>
+        <groupId>com.google.inject.extensions</groupId>
+        <artifactId>guice-multibindings</artifactId>
+        <version>3.0</version>
+    </dependency>
     <!--  for transient chef provider -->
     <dependency>
       <groupId>org.apache.jclouds</groupId>
diff --git a/core/src/main/java/org/jclouds/chef/util/ChefUtils.java b/core/src/main/java/org/jclouds/chef/util/ChefUtils.java
index 0e9e66a..aff08d3 100644
--- a/core/src/main/java/org/jclouds/chef/util/ChefUtils.java
+++ b/core/src/main/java/org/jclouds/chef/util/ChefUtils.java
@@ -25,13 +25,13 @@
 
 import org.jclouds.domain.JsonBall;
 import org.jclouds.ohai.Automatic;
-import org.jclouds.ohai.config.multibindings.MapBinder;
 
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 import com.google.common.collect.Iterables;
 import com.google.inject.Binder;
 import com.google.inject.TypeLiteral;
+import com.google.inject.multibindings.MapBinder;
 
 /**
  * 
diff --git a/core/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java b/core/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java
index acff81a..1f106ec 100644
--- a/core/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java
+++ b/core/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java
@@ -22,11 +22,11 @@
 import javax.inject.Singleton;
 
 import org.jclouds.domain.JsonBall;
-import org.jclouds.ohai.config.multibindings.MapBinder;
 import org.jclouds.ohai.suppliers.UptimeSecondsSupplier;
 
 import com.google.common.base.Supplier;
 import com.google.inject.Provides;
+import com.google.inject.multibindings.MapBinder;
 
 /**
  * Wires the components needed to parse ohai data from a JVM
diff --git a/core/src/main/java/org/jclouds/ohai/config/OhaiModule.java b/core/src/main/java/org/jclouds/ohai/config/OhaiModule.java
index 62a7630..152b120 100644
--- a/core/src/main/java/org/jclouds/ohai/config/OhaiModule.java
+++ b/core/src/main/java/org/jclouds/ohai/config/OhaiModule.java
@@ -32,7 +32,6 @@
 import org.jclouds.json.Json;
 import org.jclouds.ohai.Automatic;
 import org.jclouds.ohai.AutomaticSupplier;
-import org.jclouds.ohai.config.multibindings.MapBinder;
 import org.jclouds.ohai.functions.ByteArrayToMacAddress;
 import org.jclouds.ohai.functions.MapSetToMultimap;
 
@@ -42,6 +41,7 @@
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.TypeLiteral;
+import com.google.inject.multibindings.MapBinder;
 
 /**
  * Wires the components needed to parse ohai data
diff --git a/core/src/main/java/org/jclouds/ohai/config/multibindings/Element.java b/core/src/main/java/org/jclouds/ohai/config/multibindings/Element.java
deleted file mode 100644
index db8d16a..0000000
--- a/core/src/main/java/org/jclouds/ohai/config/multibindings/Element.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.jclouds.ohai.config.multibindings;
-
-import com.google.inject.BindingAnnotation;
-
-import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-/**
- * An internal binding annotation applied to each element in a multibinding. All
- * elements are assigned a globally-unique id to allow different modules to
- * contribute multibindings independently.
- * 
- * @author jessewilson@google.com (Jesse Wilson)
- */
-@Retention(RUNTIME)
-@BindingAnnotation
-@interface Element {
-   String setName();
-
-   int uniqueId();
-}
diff --git a/core/src/main/java/org/jclouds/ohai/config/multibindings/MapBinder.java b/core/src/main/java/org/jclouds/ohai/config/multibindings/MapBinder.java
deleted file mode 100644
index 2cde1b0..0000000
--- a/core/src/main/java/org/jclouds/ohai/config/multibindings/MapBinder.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.jclouds.ohai.config.multibindings;
-
-import static com.google.inject.util.Types.newParameterizedTypeWithOwner;
-import static org.jclouds.ohai.config.multibindings.Multibinder.checkConfiguration;
-import static org.jclouds.ohai.config.multibindings.Multibinder.checkNotNull;
-import static org.jclouds.ohai.config.multibindings.Multibinder.setOf;
-
-import java.lang.annotation.Annotation;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import org.jclouds.ohai.config.multibindings.Multibinder.RealMultibinder;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Binder;
-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.TypeLiteral;
-import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.ProviderWithDependencies;
-import com.google.inject.util.Types;
-
-/**
- * An API to bind multiple map entries separately, only to later inject them as
- * a complete map. MapBinder is intended for use in your application's module:
- * 
- * <pre>
- * <code>
- * public class SnacksModule extends AbstractModule {
- *   protected void configure() {
- *     MapBinder&lt;String, Snack&gt; mapbinder
- *         = MapBinder.newMapBinder(binder(), String.class, Snack.class);
- *     mapbinder.addBinding("twix").toInstance(new Twix());
- *     mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);
- *     mapbinder.addBinding("skittles").to(Skittles.class);
- *   }
- * }</code>
- * </pre>
- * 
- * <p>
- * With this binding, a {@link Map}{@code <String, Snack>} can now be injected:
- * 
- * <pre>
- * <code>
- * class SnackMachine {
- *   {@literal @}Inject
- *   public SnackMachine(Map&lt;String, Snack&gt; snacks) { ... }
- * }</code>
- * </pre>
- * 
- * <p>
- * In addition to binding {@code Map<K, V>}, a mapbinder will also bind
- * {@code Map<K, Provider<V>>} for lazy value provision:
- * 
- * <pre>
- * <code>
- * class SnackMachine {
- *   {@literal @}Inject
- *   public SnackMachine(Map&lt;String, Provider&lt;Snack&gt;&gt; snackSuppliers) { ... }
- * }</code>
- * </pre>
- * 
- * <p>
- * Contributing mapbindings from different modules is supported. For example, it
- * is okay to have both {@code CandyModule} and {@code ChipsModule} both create
- * their own {@code MapBinder<String, Snack>}, and to each contribute bindings
- * to the snacks map. When that map is injected, it will contain entries from
- * both modules.
- * 
- * <p>
- * The map's iteration order is consistent with the binding order. This is
- * convenient when multiple elements are contributed by the same module because
- * that module can order its bindings appropriately. Avoid relying on the
- * iteration order of elements contributed by different modules, since there is
- * no equivalent mechanism to order modules.
- * 
- * <p>
- * Values are resolved at map injection time. If a value is bound to a provider,
- * that provider's get method will be called each time the map is injected
- * (unless the binding is also scoped, or a map of providers is injected).
- * 
- * <p>
- * Annotations are used to create different maps of the same key/value type.
- * Each distinct annotation gets its own independent map.
- * 
- * <p>
- * <strong>Keys must be distinct.</strong> If the same key is bound more than
- * once, map injection will fail. However, use {@link #permitDuplicates()} in
- * order to allow duplicate keys; extra bindings to {@code Map<K, Set<V>>} and
- * {@code Map<K, Set<Provider<V>>} will be added.
- * 
- * <p>
- * <strong>Keys must be non-null.</strong> {@code addBinding(null)} will throw
- * an unchecked exception.
- * 
- * <p>
- * <strong>Values must be non-null to use map injection.</strong> If any value
- * is null, map injection will fail (although injecting a map of providers will
- * not).
- * 
- * @author dpb@google.com (David P. Baker)
- */
-public abstract class MapBinder<K, V> {
-   private MapBinder() {
-   }
-
-   /**
-    * Returns a new mapbinder that collects entries of {@code keyType}/
-    * {@code valueType} in a {@link Map} that is itself bound with no binding
-    * annotation.
-    */
-   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-      binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
-      return newMapBinder(binder, valueType, Key.get(mapOf(keyType, valueType)),
-            Key.get(mapOfProviderOf(keyType, valueType)), Key.get(mapOf(keyType, setOf(valueType))),
-            Key.get(mapOfSetOfProviderOf(keyType, valueType)),
-            Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType)));
-   }
-
-   /**
-    * Returns a new mapbinder that collects entries of {@code keyType}/
-    * {@code valueType} in a {@link Map} that is itself bound with no binding
-    * annotation.
-    */
-   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType, Class<V> valueType) {
-      return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType));
-   }
-
-   /**
-    * Returns a new mapbinder that collects entries of {@code keyType}/
-    * {@code valueType} in a {@link Map} that is itself bound with
-    * {@code annotation}.
-    */
-   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType,
-         Annotation annotation) {
-      binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
-      return newMapBinder(binder, valueType, Key.get(mapOf(keyType, valueType), annotation),
-            Key.get(mapOfProviderOf(keyType, valueType), annotation),
-            Key.get(mapOf(keyType, setOf(valueType)), annotation),
-            Key.get(mapOfSetOfProviderOf(keyType, valueType), annotation),
-            Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType), annotation));
-   }
-
-   /**
-    * Returns a new mapbinder that collects entries of {@code keyType}/
-    * {@code valueType} in a {@link Map} that is itself bound with
-    * {@code annotation}.
-    */
-   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType, Class<V> valueType,
-         Annotation annotation) {
-      return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotation);
-   }
-
-   /**
-    * Returns a new mapbinder that collects entries of {@code keyType}/
-    * {@code valueType} in a {@link Map} that is itself bound with
-    * {@code annotationType}.
-    */
-   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<K> keyType, TypeLiteral<V> valueType,
-         Class<? extends Annotation> annotationType) {
-      binder = binder.skipSources(MapBinder.class, RealMapBinder.class);
-      return newMapBinder(binder, valueType, Key.get(mapOf(keyType, valueType), annotationType),
-            Key.get(mapOfProviderOf(keyType, valueType), annotationType),
-            Key.get(mapOf(keyType, setOf(valueType)), annotationType),
-            Key.get(mapOfSetOfProviderOf(keyType, valueType), annotationType),
-            Multibinder.newSetBinder(binder, entryOfProviderOf(keyType, valueType), annotationType));
-   }
-
-   /**
-    * Returns a new mapbinder that collects entries of {@code keyType}/
-    * {@code valueType} in a {@link Map} that is itself bound with
-    * {@code annotationType}.
-    */
-   public static <K, V> MapBinder<K, V> newMapBinder(Binder binder, Class<K> keyType, Class<V> valueType,
-         Class<? extends Annotation> annotationType) {
-      return newMapBinder(binder, TypeLiteral.get(keyType), TypeLiteral.get(valueType), annotationType);
-   }
-
-   @SuppressWarnings("unchecked")
-   // a map of <K, V> is safely a Map<K, V>
-   private static <K, V> TypeLiteral<Map<K, V>> mapOf(TypeLiteral<K> keyType, TypeLiteral<V> valueType) {
-      return (TypeLiteral<Map<K, V>>) TypeLiteral.get(Types.mapOf(keyType.getType(), valueType.getType()));
-   }
-
-   @SuppressWarnings("unchecked")
-   // a provider map <K, V> is safely a Map<K, Provider<V>>
-   private static <K, V> TypeLiteral<Map<K, Provider<V>>> mapOfProviderOf(TypeLiteral<K> keyType,
-         TypeLiteral<V> valueType) {
-      return (TypeLiteral<Map<K, Provider<V>>>) TypeLiteral.get(Types.mapOf(keyType.getType(),
-            Types.providerOf(valueType.getType())));
-   }
-
-   @SuppressWarnings("unchecked")
-   // a provider map <K, Set<V>> is safely a Map<K, Set<Provider<V>>>
-   private static <K, V> TypeLiteral<Map<K, Set<Provider<V>>>> mapOfSetOfProviderOf(TypeLiteral<K> keyType,
-         TypeLiteral<V> valueType) {
-      return (TypeLiteral<Map<K, Set<Provider<V>>>>) TypeLiteral.get(Types.mapOf(keyType.getType(),
-            Types.setOf(Types.providerOf(valueType.getType()))));
-   }
-
-   @SuppressWarnings("unchecked")
-   // a provider entry <K, V> is safely a Map.Entry<K, Provider<V>>
-   private static <K, V> TypeLiteral<Map.Entry<K, Provider<V>>> entryOfProviderOf(TypeLiteral<K> keyType,
-         TypeLiteral<V> valueType) {
-      return (TypeLiteral<Entry<K, Provider<V>>>) TypeLiteral.get(newParameterizedTypeWithOwner(Map.class, Entry.class,
-            keyType.getType(), Types.providerOf(valueType.getType())));
-   }
-
-   private static <K, V> MapBinder<K, V> newMapBinder(Binder binder, TypeLiteral<V> valueType, Key<Map<K, V>> mapKey,
-         Key<Map<K, Provider<V>>> providerMapKey, Key<Map<K, Set<V>>> multimapKey,
-         Key<Map<K, Set<Provider<V>>>> providerMultimapKey, Multibinder<Entry<K, Provider<V>>> entrySetBinder) {
-      RealMapBinder<K, V> mapBinder = new RealMapBinder<K, V>(binder, valueType, mapKey, providerMapKey, multimapKey,
-            providerMultimapKey, entrySetBinder);
-      binder.install(mapBinder);
-      return mapBinder;
-   }
-
-   /**
-    * Configures the {@code MapBinder} to handle duplicate entries.
-    * <p>
-    * When multiple equal keys are bound, the value that gets included in the
-    * map is arbitrary.
-    * <p>
-    * In addition to the {@code Map<K, V>} and {@code Map<K, Provider<V>>} maps
-    * that are normally bound, a {@code Map<K, Set<V>>} and {@code Map<K,
-    * Set<Provider<V>>>} are <em>also</em> bound, which contain all values bound
-    * to each key.
-    * <p>
-    * When multiple modules contribute elements to the map, this configuration
-    * option impacts all of them.
-    * 
-    * @return this map binder
-    */
-   public abstract MapBinder<K, V> permitDuplicates();
-
-   /**
-    * Returns a binding builder used to add a new entry in the map. Each key
-    * must be distinct (and non-null). Bound providers will be evaluated each
-    * time the map is injected.
-    * 
-    * <p>
-    * It is an error to call this method without also calling one of the
-    * {@code to} methods on the returned binding builder.
-    * 
-    * <p>
-    * Scoping elements independently is supported. Use the {@code in} method to
-    * specify a binding scope.
-    */
-   public abstract LinkedBindingBuilder<V> addBinding(K key);
-
-   /**
-    * The actual mapbinder plays several roles:
-    * 
-    * <p>
-    * As a MapBinder, it acts as a factory for LinkedBindingBuilders for each of
-    * the map's values. It delegates to a {@link Multibinder} of entries (keys
-    * to value providers).
-    * 
-    * <p>
-    * As a Module, it installs the binding to the map itself, as well as to a
-    * corresponding map whose values are providers. It uses the entry set
-    * multibinder to construct the map and the provider map.
-    * 
-    * <p>
-    * As a module, this implements equals() and hashcode() in order to trick
-    * Guice into executing its configure() method only once. That makes it so
-    * that multiple mapbinders can be created for the same target map, but only
-    * one is bound. Since the list of bindings is retrieved from the injector
-    * itself (and not the mapbinder), each mapbinder has access to all
-    * contributions from all equivalent mapbinders.
-    * 
-    * <p>
-    * Rather than binding a single Map.Entry&lt;K, V&gt;, the map binder binds
-    * keys and values independently. This allows the values to be properly
-    * scoped.
-    * 
-    * <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 {
-      private final TypeLiteral<V> valueType;
-      private final Key<Map<K, V>> mapKey;
-      private final Key<Map<K, Provider<V>>> providerMapKey;
-      private final Key<Map<K, Set<V>>> multimapKey;
-      private final Key<Map<K, Set<Provider<V>>>> providerMultimapKey;
-      private final RealMultibinder<Map.Entry<K, Provider<V>>> entrySetBinder;
-
-      /*
-       * the target injector's binder. non-null until initialization, null
-       * afterwards
-       */
-      private Binder binder;
-
-      private RealMapBinder(Binder binder, TypeLiteral<V> valueType, Key<Map<K, V>> mapKey,
-            Key<Map<K, Provider<V>>> providerMapKey, Key<Map<K, Set<V>>> multimapKey,
-            Key<Map<K, Set<Provider<V>>>> providerMultimapKey, Multibinder<Map.Entry<K, Provider<V>>> entrySetBinder) {
-         this.valueType = valueType;
-         this.mapKey = mapKey;
-         this.providerMapKey = providerMapKey;
-         this.multimapKey = multimapKey;
-         this.providerMultimapKey = providerMultimapKey;
-         this.entrySetBinder = (RealMultibinder<Entry<K, Provider<V>>>) entrySetBinder;
-         this.binder = binder;
-      }
-
-      @Override
-      public MapBinder<K, V> permitDuplicates() {
-         entrySetBinder.permitDuplicates();
-         binder.install(new MultimapBinder<K, V>(multimapKey, providerMultimapKey, entrySetBinder.getSetKey()));
-         return this;
-      }
-
-      /**
-       * This creates two bindings. One for the {@code Map.Entry<K,
-       * Provider<V>>} and another for {@code V}.
-       */
-      @Override
-      public LinkedBindingBuilder<V> addBinding(K key) {
-         checkNotNull(key, "key");
-         checkConfiguration(!isInitialized(), "MapBinder was already initialized");
-
-         Key<V> valueKey = Key.get(valueType, new RealElement(entrySetBinder.getSetName()));
-         entrySetBinder.addBinding().toInstance(new MapEntry<K, Provider<V>>(key, binder.getProvider(valueKey)));
-         return binder.bind(valueKey);
-      }
-
-      public void configure(Binder binder) {
-         checkConfiguration(!isInitialized(), "MapBinder was already initialized");
-
-         final ImmutableSet<Dependency<?>> dependencies = ImmutableSet.<Dependency<?>> of(Dependency.get(entrySetBinder
-               .getSetKey()));
-
-         // Binds a Map<K, Provider<V>> from a collection of Map<Entry<K,
-         // Provider<V>>.
-         final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider = binder.getProvider(entrySetBinder.getSetKey());
-         binder.bind(providerMapKey).toProvider(new ProviderWithDependencies<Map<K, Provider<V>>>() {
-            private Map<K, Provider<V>> providerMap;
-
-            @SuppressWarnings("unused")
-            @Inject
-            void initialize(Injector injector) {
-               RealMapBinder.this.binder = null;
-               boolean permitDuplicates = entrySetBinder.permitsDuplicates(injector);
-
-               Map<K, Provider<V>> providerMapMutable = new LinkedHashMap<K, Provider<V>>();
-               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());
-               }
-
-               providerMap = ImmutableMap.copyOf(providerMapMutable);
-            }
-
-            public Map<K, Provider<V>> get() {
-               return providerMap;
-            }
-
-            public Set<Dependency<?>> getDependencies() {
-               return dependencies;
-            }
-         });
-
-         final Provider<Map<K, Provider<V>>> mapProvider = binder.getProvider(providerMapKey);
-         binder.bind(mapKey).toProvider(new ProviderWithDependencies<Map<K, V>>() {
-            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();
-                  checkConfiguration(value != null, "Map injection failed due to null value for key \"%s\"", key);
-                  map.put(key, value);
-               }
-               return Collections.unmodifiableMap(map);
-            }
-
-            public Set<Dependency<?>> getDependencies() {
-               return dependencies;
-            }
-         });
-      }
-
-      private boolean isInitialized() {
-         return binder == null;
-      }
-
-      @Override
-      public boolean equals(Object o) {
-         return o instanceof RealMapBinder<?, ?> && ((RealMapBinder<?, ?>) o).mapKey.equals(mapKey);
-      }
-
-      @Override
-      public int hashCode() {
-         return mapKey.hashCode();
-      }
-
-      /**
-       * Binds {@code Map<K, Set<V>>} and {{@code Map<K, Set<Provider<V>>>}.
-       */
-      private static final class MultimapBinder<K, V> implements Module {
-
-         private final Key<Map<K, Set<V>>> multimapKey;
-         private final Key<Map<K, Set<Provider<V>>>> providerMultimapKey;
-         private final Key<Set<Entry<K, Provider<V>>>> entrySetKey;
-
-         public MultimapBinder(Key<Map<K, Set<V>>> multimapKey, Key<Map<K, Set<Provider<V>>>> providerMultimapKey,
-               Key<Set<Entry<K, Provider<V>>>> entrySetKey) {
-            this.multimapKey = multimapKey;
-            this.providerMultimapKey = providerMultimapKey;
-            this.entrySetKey = entrySetKey;
-         }
-
-         public void configure(Binder binder) {
-            final ImmutableSet<Dependency<?>> dependencies = ImmutableSet.<Dependency<?>> of(Dependency
-                  .get(entrySetKey));
-
-            final Provider<Set<Entry<K, Provider<V>>>> entrySetProvider = binder.getProvider(entrySetKey);
-            // Binds a Map<K, Set<Provider<V>>> from a collection of
-            // Map<Entry<K, Provider<V>> if
-            // permitDuplicates was called.
-            binder.bind(providerMultimapKey).toProvider(new ProviderWithDependencies<Map<K, Set<Provider<V>>>>() {
-               private Map<K, Set<Provider<V>>> providerMultimap;
-
-               @SuppressWarnings("unused")
-               @Inject
-               void initialize(Injector injector) {
-                  Map<K, ImmutableSet.Builder<Provider<V>>> providerMultimapMutable = new LinkedHashMap<K, ImmutableSet.Builder<Provider<V>>>();
-                  for (Entry<K, Provider<V>> entry : entrySetProvider.get()) {
-                     if (!providerMultimapMutable.containsKey(entry.getKey())) {
-                        providerMultimapMutable.put(entry.getKey(), ImmutableSet.<Provider<V>> builder());
-                     }
-                     providerMultimapMutable.get(entry.getKey()).add(entry.getValue());
-                  }
-
-                  ImmutableMap.Builder<K, Set<Provider<V>>> providerMultimapBuilder = ImmutableMap.builder();
-                  for (Entry<K, ImmutableSet.Builder<Provider<V>>> entry : providerMultimapMutable.entrySet()) {
-                     providerMultimapBuilder.put(entry.getKey(), entry.getValue().build());
-                  }
-                  providerMultimap = providerMultimapBuilder.build();
-               }
-
-               public Map<K, Set<Provider<V>>> get() {
-                  return providerMultimap;
-               }
-
-               public Set<Dependency<?>> getDependencies() {
-                  return dependencies;
-               }
-            });
-
-            final Provider<Map<K, Set<Provider<V>>>> multimapProvider = binder.getProvider(providerMultimapKey);
-            binder.bind(multimapKey).toProvider(new ProviderWithDependencies<Map<K, Set<V>>>() {
-
-               public Map<K, Set<V>> get() {
-                  ImmutableMap.Builder<K, Set<V>> multimapBuilder = ImmutableMap.builder();
-                  for (Entry<K, Set<Provider<V>>> entry : multimapProvider.get().entrySet()) {
-                     K key = entry.getKey();
-                     ImmutableSet.Builder<V> valuesBuilder = ImmutableSet.builder();
-                     for (Provider<V> valueProvider : entry.getValue()) {
-                        V value = valueProvider.get();
-                        checkConfiguration(value != null, "Multimap injection failed due to null value for key \"%s\"",
-                              key);
-                        valuesBuilder.add(value);
-                     }
-                     multimapBuilder.put(key, valuesBuilder.build());
-                  }
-                  return multimapBuilder.build();
-               }
-
-               public Set<Dependency<?>> getDependencies() {
-                  return dependencies;
-               }
-            });
-         }
-      }
-
-      private static final class MapEntry<K, V> implements Map.Entry<K, V> {
-         private final K key;
-         private final V value;
-
-         private MapEntry(K key, V value) {
-            this.key = key;
-            this.value = value;
-         }
-
-         public K getKey() {
-            return key;
-         }
-
-         public V getValue() {
-            return value;
-         }
-
-         public V setValue(V value) {
-            throw new UnsupportedOperationException();
-         }
-
-         @Override
-         public boolean equals(Object obj) {
-            return obj instanceof Map.Entry<?, ?> && key.equals(((Map.Entry<?, ?>) obj).getKey())
-                  && value.equals(((Map.Entry<?, ?>) obj).getValue());
-         }
-
-         @Override
-         public int hashCode() {
-            return 127 * ("key".hashCode() ^ key.hashCode()) + 127 * ("value".hashCode() ^ value.hashCode());
-         }
-
-         @Override
-         public String toString() {
-            return "MapEntry(" + key + ", " + value + ")";
-         }
-      }
-   }
-}
diff --git a/core/src/main/java/org/jclouds/ohai/config/multibindings/Multibinder.java b/core/src/main/java/org/jclouds/ohai/config/multibindings/Multibinder.java
deleted file mode 100644
index 3d521b2..0000000
--- a/core/src/main/java/org/jclouds/ohai/config/multibindings/Multibinder.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.jclouds.ohai.config.multibindings;
-
-import static com.google.inject.name.Names.named;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.inject.AbstractModule;
-import com.google.inject.Binder;
-import com.google.inject.Binding;
-import com.google.inject.ConfigurationException;
-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.TypeLiteral;
-import com.google.inject.binder.LinkedBindingBuilder;
-import com.google.inject.spi.Dependency;
-import com.google.inject.spi.HasDependencies;
-import com.google.inject.spi.Message;
-import com.google.inject.spi.Toolable;
-import com.google.inject.util.Types;
-
-/**
- * 
- * An API to bind multiple values separately, only to later inject them as a
- * complete collection. Multibinder is intended for use in your application's
- * module:
- * 
- * <pre>
- * <code>
- * public class SnacksModule extends AbstractModule {
- *   protected void configure() {
- *     Multibinder&lt;Snack&gt; multibinder
- *         = Multibinder.newSetBinder(binder(), Snack.class);
- *     multibinder.addBinding().toInstance(new Twix());
- *     multibinder.addBinding().toProvider(SnickersProvider.class);
- *     multibinder.addBinding().to(Skittles.class);
- *   }
- * }</code>
- * </pre>
- * 
- * <p>
- * With this binding, a {@link Set}{@code <Snack>} can now be injected:
- * 
- * <pre>
- * <code>
- * class SnackMachine {
- *   {@literal @}Inject
- *   public SnackMachine(Set&lt;Snack&gt; snacks) { ... }
- * }</code>
- * </pre>
- * 
- * <p>
- * Contributing multibindings from different modules is supported. For example,
- * it is okay to have both {@code CandyModule} and {@code ChipsModule} to both
- * create their own {@code Multibinder<Snack>}, and to each contribute bindings
- * to the set of snacks. When that set is injected, it will contain elements
- * from both modules.
- * 
- * <p>
- * The set's iteration order is consistent with the binding order. This is
- * convenient when multiple elements are contributed by the same module because
- * that module can order its bindings appropriately. Avoid relying on the
- * iteration order of elements contributed by different modules, since there is
- * no equivalent mechanism to order modules.
- * 
- * <p>
- * Elements are resolved at set injection time. If an element is bound to a
- * provider, that provider's get method will be called each time the set is
- * injected (unless the binding is also scoped).
- * 
- * <p>
- * Annotations are be used to create different sets of the same element type.
- * Each distinct annotation gets its own independent collection of elements.
- * 
- * <p>
- * <strong>Elements must be distinct.</strong> If multiple bound elements have
- * the same value, set injection will fail.
- * 
- * <p>
- * <strong>Elements must be non-null.</strong> If any set element is null, set
- * injection will fail.
- * 
- * @author jessewilson@google.com (Jesse Wilson)
- */
-public abstract class Multibinder<T> {
-   private Multibinder() {
-   }
-
-   /**
-    * Returns a new multibinder that collects instances of {@code type} in a
-    * {@link Set} that is itself bound with no binding annotation.
-    */
-   public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type) {
-      binder = binder.skipSources(RealMultibinder.class, Multibinder.class);
-      RealMultibinder<T> result = new RealMultibinder<T>(binder, type, "", Key.get(Multibinder.<T> setOf(type)));
-      binder.install(result);
-      return result;
-   }
-
-   /**
-    * Returns a new multibinder that collects instances of {@code type} in a
-    * {@link Set} that is itself bound with no binding annotation.
-    */
-   public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type) {
-      return newSetBinder(binder, TypeLiteral.get(type));
-   }
-
-   /**
-    * Returns a new multibinder that collects instances of {@code type} in a
-    * {@link Set} that is itself bound with {@code annotation}.
-    */
-   public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type, Annotation annotation) {
-      binder = binder.skipSources(RealMultibinder.class, Multibinder.class);
-      RealMultibinder<T> result = new RealMultibinder<T>(binder, type, annotation.toString(), Key.get(
-            Multibinder.<T> setOf(type), annotation));
-      binder.install(result);
-      return result;
-   }
-
-   /**
-    * Returns a new multibinder that collects instances of {@code type} in a
-    * {@link Set} that is itself bound with {@code annotation}.
-    */
-   public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type, Annotation annotation) {
-      return newSetBinder(binder, TypeLiteral.get(type), annotation);
-   }
-
-   /**
-    * Returns a new multibinder that collects instances of {@code type} in a
-    * {@link Set} that is itself bound with {@code annotationType}.
-    */
-   public static <T> Multibinder<T> newSetBinder(Binder binder, TypeLiteral<T> type,
-         Class<? extends Annotation> annotationType) {
-      binder = binder.skipSources(RealMultibinder.class, Multibinder.class);
-      RealMultibinder<T> result = new RealMultibinder<T>(binder, type, "@" + annotationType.getName(), Key.get(
-            Multibinder.<T> setOf(type), annotationType));
-      binder.install(result);
-      return result;
-   }
-
-   /**
-    * Returns a new multibinder that collects instances of {@code type} in a
-    * {@link Set} that is itself bound with {@code annotationType}.
-    */
-   public static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type,
-         Class<? extends Annotation> annotationType) {
-      return newSetBinder(binder, TypeLiteral.get(type), annotationType);
-   }
-
-   @SuppressWarnings("unchecked")
-   // wrapping a T in a Set safely returns a Set<T>
-   static <T> TypeLiteral<Set<T>> setOf(TypeLiteral<T> elementType) {
-      Type type = Types.setOf(elementType.getType());
-      return (TypeLiteral<Set<T>>) TypeLiteral.get(type);
-   }
-
-   /**
-    * Configures the bound set to silently discard duplicate elements. When
-    * multiple equal values are bound, the one that gets included is arbitrary.
-    * When multiple modules contribute elements to the set, this configuration
-    * option impacts all of them.
-    * 
-    * @return this multibinder
-    */
-   public abstract Multibinder<T> permitDuplicates();
-
-   /**
-    * Returns a binding builder used to add a new element in the set. Each bound
-    * element must have a distinct value. Bound providers will be evaluated each
-    * time the set is injected.
-    * 
-    * <p>
-    * It is an error to call this method without also calling one of the
-    * {@code to} methods on the returned binding builder.
-    * 
-    * <p>
-    * Scoping elements independently is supported. Use the {@code in} method to
-    * specify a binding scope.
-    */
-   public abstract LinkedBindingBuilder<T> addBinding();
-
-   /**
-    * The actual multibinder plays several roles:
-    * 
-    * <p>
-    * As a Multibinder, it acts as a factory for LinkedBindingBuilders for each
-    * of the set's elements. Each binding is given an annotation that identifies
-    * it as a part of this set.
-    * 
-    * <p>
-    * As a Module, it installs the binding to the set itself. As a module, this
-    * implements equals() and hashcode() in order to trick Guice into executing
-    * its configure() method only once. That makes it so that multiple
-    * multibinders can be created for the same target collection, but only one
-    * is bound. Since the list of bindings is retrieved from the injector itself
-    * (and not the multibinder), each multibinder has access to all
-    * contributions from all multibinders.
-    * 
-    * <p>
-    * As a Provider, this constructs the set instances.
-    * 
-    * <p>
-    * We use a subclass to hide 'implements Module, Provider' from the public
-    * API.
-    */
-   static final class RealMultibinder<T> extends Multibinder<T> implements Module, Provider<Set<T>>, HasDependencies {
-
-      private final TypeLiteral<T> elementType;
-      private final String setName;
-      private final Key<Set<T>> setKey;
-      private final Key<Boolean> permitDuplicatesKey;
-
-      /*
-       * the target injector's binder. non-null until initialization, null
-       * afterwards
-       */
-      private Binder binder;
-
-      /*
-       * a provider for each element in the set. null until initialization,
-       * non-null afterwards
-       */
-      private List<Provider<T>> providers;
-      private Set<Dependency<?>> dependencies;
-
-      /**
-       * whether duplicates are allowed. Possibly configured by a different
-       * instance
-       */
-      private boolean permitDuplicates;
-
-      private RealMultibinder(Binder binder, TypeLiteral<T> elementType, String setName, Key<Set<T>> setKey) {
-         this.binder = checkNotNull(binder, "binder");
-         this.elementType = checkNotNull(elementType, "elementType");
-         this.setName = checkNotNull(setName, "setName");
-         this.setKey = checkNotNull(setKey, "setKey");
-         this.permitDuplicatesKey = Key.get(Boolean.class, named(toString() + " permits duplicates"));
-      }
-
-      public void configure(Binder binder) {
-         checkConfiguration(!isInitialized(), "Multibinder was already initialized");
-         binder.bind(setKey).toProvider(this);
-      }
-
-      @Override
-      public Multibinder<T> permitDuplicates() {
-         binder.install(new PermitDuplicatesModule(permitDuplicatesKey));
-         return this;
-      }
-
-      @Override
-      public LinkedBindingBuilder<T> addBinding() {
-         checkConfiguration(!isInitialized(), "Multibinder was already initialized");
-
-         return binder.bind(Key.get(elementType, new RealElement(setName)));
-      }
-
-      /**
-       * Invoked by Guice at Injector-creation time to prepare providers for
-       * each element in this set. At this time the set's size is known, but its
-       * contents are only evaluated when get() is invoked.
-       */
-      @Toolable
-      @Inject
-      void initialize(Injector injector) {
-         providers = Lists.newArrayList();
-         List<Dependency<?>> dependencies = Lists.newArrayList();
-         for (Binding<?> entry : injector.findBindingsByType(elementType)) {
-
-            if (keyMatches(entry.getKey())) {
-               @SuppressWarnings("unchecked")
-               // protected by findBindingsByType()
-               Binding<T> binding = (Binding<T>) entry;
-               providers.add(binding.getProvider());
-               dependencies.add(Dependency.get(binding.getKey()));
-            }
-         }
-
-         this.dependencies = ImmutableSet.copyOf(dependencies);
-         this.permitDuplicates = permitsDuplicates(injector);
-         this.binder = null;
-      }
-
-      boolean permitsDuplicates(Injector injector) {
-         return injector.getBindings().containsKey(permitDuplicatesKey);
-      }
-
-      private boolean keyMatches(Key<?> key) {
-         return key.getTypeLiteral().equals(elementType) && key.getAnnotation() instanceof Element
-               && ((Element) key.getAnnotation()).setName().equals(setName);
-      }
-
-      private boolean isInitialized() {
-         return binder == null;
-      }
-
-      public Set<T> get() {
-         checkConfiguration(isInitialized(), "Multibinder is not initialized");
-
-         Set<T> result = new LinkedHashSet<T>();
-         for (Provider<T> provider : providers) {
-            final T newValue = provider.get();
-            checkConfiguration(newValue != null, "Set injection failed due to null element");
-            checkConfiguration(result.add(newValue) || permitDuplicates,
-                  "Set injection failed due to duplicated element \"%s\"", newValue);
-         }
-         return Collections.unmodifiableSet(result);
-      }
-
-      String getSetName() {
-         return setName;
-      }
-
-      Key<Set<T>> getSetKey() {
-         return setKey;
-      }
-
-      public Set<Dependency<?>> getDependencies() {
-         return dependencies;
-      }
-
-      @Override
-      public boolean equals(Object o) {
-         return o instanceof RealMultibinder<?> && ((RealMultibinder<?>) o).setKey.equals(setKey);
-      }
-
-      @Override
-      public int hashCode() {
-         return setKey.hashCode();
-      }
-
-      @Override
-      public String toString() {
-         return new StringBuilder().append(setName).append(setName.length() > 0 ? " " : "").append("Multibinder<")
-               .append(elementType).append(">").toString();
-      }
-   }
-
-   /**
-    * We install the permit duplicates configuration as its own binding, all by
-    * itself. This way, if only one of a multibinder's users remember to call
-    * permitDuplicates(), they're still permitted.
-    */
-   private static class PermitDuplicatesModule extends AbstractModule {
-      private final Key<Boolean> key;
-
-      PermitDuplicatesModule(Key<Boolean> key) {
-         this.key = key;
-      }
-
-      @Override
-      protected void configure() {
-         bind(key).toInstance(true);
-      }
-
-      @Override
-      public boolean equals(Object o) {
-         return o instanceof PermitDuplicatesModule && ((PermitDuplicatesModule) o).key.equals(key);
-      }
-
-      @Override
-      public int hashCode() {
-         return getClass().hashCode() ^ key.hashCode();
-      }
-   }
-
-   static void checkConfiguration(boolean condition, String format, Object... args) {
-      if (condition) {
-         return;
-      }
-
-      throw new ConfigurationException(ImmutableSet.of(new Message(String.format(format, args))));
-   }
-
-   static <T> T checkNotNull(T reference, String name) {
-      if (reference != null) {
-         return reference;
-      }
-
-      NullPointerException npe = new NullPointerException(name);
-      throw new ConfigurationException(ImmutableSet.of(new Message(ImmutableList.of(), npe.toString(), npe)));
-   }
-}
diff --git a/core/src/main/java/org/jclouds/ohai/config/multibindings/RealElement.java b/core/src/main/java/org/jclouds/ohai/config/multibindings/RealElement.java
deleted file mode 100644
index f727445..0000000
--- a/core/src/main/java/org/jclouds/ohai/config/multibindings/RealElement.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.jclouds.ohai.config.multibindings;
-
-import java.lang.annotation.Annotation;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * @author jessewilson@google.com (Jesse Wilson)
- */
-class RealElement implements Element {
-   private static final AtomicInteger nextUniqueId = new AtomicInteger(1);
-
-   private final int uniqueId;
-   private final String setName;
-
-   RealElement(String setName) {
-      uniqueId = nextUniqueId.getAndIncrement();
-      this.setName = setName;
-   }
-
-   public String setName() {
-      return setName;
-   }
-
-   public int uniqueId() {
-      return uniqueId;
-   }
-
-   public Class<? extends Annotation> annotationType() {
-      return Element.class;
-   }
-
-   @Override
-   public String toString() {
-      return "@" + Element.class.getName() + "(setName=" + setName + ",uniqueId=" + uniqueId + ")";
-   }
-
-   @Override
-   public boolean equals(Object o) {
-      return o instanceof Element && ((Element) o).setName().equals(setName())
-            && ((Element) o).uniqueId() == uniqueId();
-   }
-
-   @Override
-   public int hashCode() {
-      return 127 * ("setName".hashCode() ^ setName.hashCode()) + 127 * ("uniqueId".hashCode() ^ uniqueId);
-   }
-}
diff --git a/core/src/main/java/org/jclouds/ohai/config/multibindings/package-info.java b/core/src/main/java/org/jclouds/ohai/config/multibindings/package-info.java
deleted file mode 100644
index cccfea4..0000000
--- a/core/src/main/java/org/jclouds/ohai/config/multibindings/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-/**
- *  Taken from r1154 of Guice, as they decided to stop supporting multiple bindings and instead silently throw them away.
- */
-package org.jclouds.ohai.config.multibindings;
-
diff --git a/core/src/test/java/org/jclouds/ohai/config/OhaiModuleTest.java b/core/src/test/java/org/jclouds/ohai/config/OhaiModuleTest.java
index 213106d..e2bed2e 100644
--- a/core/src/test/java/org/jclouds/ohai/config/OhaiModuleTest.java
+++ b/core/src/test/java/org/jclouds/ohai/config/OhaiModuleTest.java
@@ -31,7 +31,6 @@
 import org.jclouds.json.Json;
 import org.jclouds.json.config.GsonModule;
 import org.jclouds.ohai.Automatic;
-import org.jclouds.ohai.config.multibindings.MapBinder;
 import org.jclouds.rest.annotations.ApiVersion;
 import org.testng.annotations.Test;
 
@@ -41,6 +40,7 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.TypeLiteral;
+import com.google.inject.multibindings.MapBinder;
 import com.google.inject.util.Providers;
 
 /**
