Change exportDeps boolean to list exportedDeps.

Test Plan: Unit tests.
diff --git a/DEFS b/DEFS
index 792f4a8..6827378 100644
--- a/DEFS
+++ b/DEFS
@@ -6,7 +6,7 @@
     name,
     srcs=[],
     resources=[],
-    export_deps=False,
+    exported_deps=[],
     source='7',
     target='7',
     proguard_config=None,
@@ -17,7 +17,7 @@
     name=name,
     srcs=srcs,
     resources=resources,
-    export_deps=export_deps,
+    exported_deps=exported_deps,
     source=source,
     target=target,
     proguard_config=proguard_config,
diff --git a/lib/BUCK b/lib/BUCK
index 29d63a0..204a93c 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -71,12 +71,12 @@
 
 java_library(
     name = 'jackson',
-    deps = [
+    deps = [],
+    exported_deps = [
       ':jackson-annotations',
       ':jackson-core',
       ':jackson-databind',
     ],
-    export_deps = True,
     visibility = [
       '//src/com/facebook/buck/event:event',
     ],
diff --git a/src/com/facebook/buck/android/AndroidLibraryRule.java b/src/com/facebook/buck/android/AndroidLibraryRule.java
index 2ae8687..b421169 100644
--- a/src/com/facebook/buck/android/AndroidLibraryRule.java
+++ b/src/com/facebook/buck/android/AndroidLibraryRule.java
@@ -25,6 +25,7 @@
 import com.facebook.buck.model.BuildTarget;
 import com.facebook.buck.model.BuildTargetPattern;
 import com.facebook.buck.rules.AbstractBuildRuleBuilderParams;
+import com.facebook.buck.rules.BuildRule;
 import com.facebook.buck.rules.BuildRuleParams;
 import com.facebook.buck.rules.BuildRuleResolver;
 import com.facebook.buck.rules.BuildRuleType;
@@ -35,6 +36,7 @@
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSortedSet;
 
 import java.io.IOException;
 import java.util.List;
@@ -61,7 +63,7 @@
         srcs,
         resources,
         proguardConfig,
-        /* exportDeps */ false,
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(),
         javacOptions);
     this.manifestFile = Preconditions.checkNotNull(manifestFile);
   }
diff --git a/src/com/facebook/buck/command/Project.java b/src/com/facebook/buck/command/Project.java
index 1cc14cc..a6c2e90 100644
--- a/src/com/facebook/buck/command/Project.java
+++ b/src/com/facebook/buck/command/Project.java
@@ -35,6 +35,7 @@
 import com.facebook.buck.rules.BuildRule;
 import com.facebook.buck.rules.Buildable;
 import com.facebook.buck.rules.DependencyGraph;
+import com.facebook.buck.rules.ExportDependencies;
 import com.facebook.buck.rules.JavaPackageFinder;
 import com.facebook.buck.rules.ProjectConfigRule;
 import com.facebook.buck.rules.SourceRoot;
@@ -740,10 +741,16 @@
 
       @Override
       public ImmutableSet<BuildRule> visit(BuildRule dep) {
-        boolean depShouldExportDeps = dep.getExportDeps() || rule.getProperties().is(PACKAGING);
-        boolean shouldVisitDeps = (dep.getProperties().is(LIBRARY) && (depShouldExportDeps))
-            || (dep instanceof AndroidResourceRule)
-            || dep == rule;
+        ImmutableSet<BuildRule> depsToVisit;
+        if (rule.getProperties().is(PACKAGING) ||
+            dep instanceof AndroidResourceRule ||
+            dep == rule) {
+          depsToVisit = dep.getDeps();
+        } else if (dep.getProperties().is(LIBRARY) && dep instanceof ExportDependencies) {
+          depsToVisit = ((ExportDependencies)dep).getExportedDeps();
+        } else {
+          depsToVisit = ImmutableSet.of();
+        }
 
         // Special Case: If we are traversing the test_target and we encounter a library rule in the
         // same package that is not the src_target, then we should traverse the deps. Consider the
@@ -774,10 +781,10 @@
         // the current directory should be treated as a source folder with test sources, but it
         // should contain the union of :lib and :test's deps as dependent modules.
         if (isForTests
-            && !shouldVisitDeps
+            && depsToVisit.isEmpty()
             && dep.getBuildTarget().getBasePath().equals(basePathForRule)
             && !dep.equals(srcTarget)) {
-          shouldVisitDeps = true;
+          depsToVisit = dep.getDeps();
         }
 
         DependentModule dependentModule;
@@ -789,12 +796,12 @@
           String moduleName = getIntellijNameForRule(dep);
           dependentModule = DependentModule.newModule(dep.getBuildTarget(), moduleName);
         } else if (dep.getFullyQualifiedName().startsWith(ANDROID_GEN_BUILD_TARGET_PREFIX)) {
-          return maybeVisitAllDeps(dep, shouldVisitDeps);
+          return depsToVisit;
         } else if (dep instanceof JavaLibraryRule || dep instanceof AndroidResourceRule) {
           String moduleName = getIntellijNameForRule(dep);
           dependentModule = DependentModule.newModule(dep.getBuildTarget(), moduleName);
         } else {
-          return maybeVisitAllDeps(dep, shouldVisitDeps);
+          return depsToVisit;
         }
 
         if (isForTests) {
@@ -818,7 +825,7 @@
           modulesToAdd.add(dependentModule);
         }
 
-        return maybeVisitAllDeps(dep, shouldVisitDeps);
+        return depsToVisit;
       }
 
       @Override
diff --git a/src/com/facebook/buck/java/DefaultJavaLibraryRule.java b/src/com/facebook/buck/java/DefaultJavaLibraryRule.java
index da8c2ee..b9c9fee 100644
--- a/src/com/facebook/buck/java/DefaultJavaLibraryRule.java
+++ b/src/com/facebook/buck/java/DefaultJavaLibraryRule.java
@@ -38,6 +38,7 @@
 import com.facebook.buck.rules.BuildableContext;
 import com.facebook.buck.rules.BuildableProperties;
 import com.facebook.buck.rules.DoNotUseAbstractBuildable;
+import com.facebook.buck.rules.ExportDependencies;
 import com.facebook.buck.rules.JavaPackageFinder;
 import com.facebook.buck.rules.OnDiskBuildInfo;
 import com.facebook.buck.rules.ResourcesAttributeBuilder;
@@ -101,7 +102,7 @@
  * from the {@code //src/com/facebook/feed/model:model} rule.
  */
 public class DefaultJavaLibraryRule extends DoNotUseAbstractBuildable
-    implements JavaLibraryRule, AbiRule, HasJavaSrcs, HasClasspathEntries {
+    implements JavaLibraryRule, AbiRule, HasJavaSrcs, HasClasspathEntries, ExportDependencies {
 
   private final static BuildableProperties OUTPUT_TYPE = new BuildableProperties(LIBRARY);
 
@@ -116,7 +117,7 @@
   private final Optional<String> proguardConfig;
 
 
-  private final boolean exportDeps;
+  private final ImmutableSortedSet<BuildRule> exportedDeps;
 
   private final Supplier<ImmutableSetMultimap<JavaLibraryRule, String>> outputClasspathEntriesSupplier;
 
@@ -187,13 +188,13 @@
                                    Set<String> srcs,
                                    Set<? extends SourcePath> resources,
                                    Optional<String> proguardConfig,
-                                   boolean exportDeps,
+                                   Set<BuildRule> exportedDeps,
                                    JavacOptions javacOptions) {
     super(buildRuleParams);
     this.srcs = ImmutableSortedSet.copyOf(srcs);
     this.resources = ImmutableSortedSet.copyOf(resources);
     this.proguardConfig = Preconditions.checkNotNull(proguardConfig);
-    this.exportDeps = exportDeps;
+    this.exportedDeps = ImmutableSortedSet.copyOf(exportedDeps);
     this.javacOptions = Preconditions.checkNotNull(javacOptions);
 
     if (!srcs.isEmpty() || !resources.isEmpty()) {
@@ -213,21 +214,26 @@
         Suppliers.memoize(new Supplier<ImmutableSetMultimap<JavaLibraryRule, String>>() {
           @Override
           public ImmutableSetMultimap<JavaLibraryRule, String> get() {
-            ImmutableSetMultimap<JavaLibraryRule, String> outputClasspathEntries;
+            ImmutableSetMultimap.Builder<JavaLibraryRule, String> outputClasspathBuilder =
+                ImmutableSetMultimap.builder();
+            Iterable<JavaLibraryRule> javaExportedLibraryDeps = Iterables.filter(
+                getExportedDeps(),
+                JavaLibraryRule.class);
 
-            // If this java_library exports its dependencies then just return the transitive
-            // dependencies.
-            if (DefaultJavaLibraryRule.this.exportDeps) {
-              outputClasspathEntries = getTransitiveClasspathEntries();
-            } else if (outputJar.isPresent()) {
-              outputClasspathEntries = ImmutableSetMultimap.<JavaLibraryRule, String>builder()
-                  .put(DefaultJavaLibraryRule.this, getPathToOutputFile())
-                  .build();
-            } else {
-              outputClasspathEntries = ImmutableSetMultimap.of();
+            for (JavaLibraryRule rule : javaExportedLibraryDeps) {
+              outputClasspathBuilder.putAll(rule, rule.getOutputClasspathEntries().values());
+              // If we have any exported deps, add an entry mapping ourselves to to their,
+              // classpaths so when suggesting libraries to add we know that adding this library
+              // would pull in it's deps.
+              outputClasspathBuilder.putAll(DefaultJavaLibraryRule.this,
+                  rule.getOutputClasspathEntries().values());
             }
 
-            return outputClasspathEntries;
+            if (outputJar.isPresent()) {
+              outputClasspathBuilder.put(DefaultJavaLibraryRule.this, getPathToOutputFile());
+            }
+
+            return outputClasspathBuilder.build();
           }
         });
 
@@ -240,11 +246,17 @@
             ImmutableSetMultimap<JavaLibraryRule, String> classpathEntriesForDeps =
                 Classpaths.getClasspathEntries(getDeps());
 
+            ImmutableSetMultimap<JavaLibraryRule, String> classpathEntriesForExportedsDeps =
+                Classpaths.getClasspathEntries(getExportedDeps());
+
             classpathEntries.putAll(classpathEntriesForDeps);
 
-            if (DefaultJavaLibraryRule.this.exportDeps) {
+            // If we have any exported deps, add an entry mapping ourselves to to their classpaths,
+            // so when suggesting libraries to add we know that adding this library would pull in
+            // it's deps.
+            if (!classpathEntriesForExportedsDeps.isEmpty()) {
               classpathEntries.putAll(DefaultJavaLibraryRule.this,
-                  classpathEntriesForDeps.values());
+                  classpathEntriesForExportedsDeps.values());
             }
 
             // Only add ourselves to the classpath if there's a jar to be built.
@@ -330,15 +342,11 @@
    * @return total ABI key containing also the ABI keys of the dependencies.
    */
   protected Sha1HashCode createTotalAbiKey(Sha1HashCode abiKey) {
-    if (!getExportDeps()) {
+    if (getExportedDeps().isEmpty()) {
       return abiKey;
     }
 
     SortedSet<JavaLibraryRule> depsForAbiKey = getDepsForAbiKey();
-    // If there are no deps to consider, just return the ABI Key for this rule.
-    if (depsForAbiKey.isEmpty()) {
-      return abiKey;
-    }
 
     // Hash the ABI keys of all dependencies together with ABI key for the current rule.
     Hasher hasher = createHasherWithAbiKeyForDeps(depsForAbiKey);
@@ -432,10 +440,10 @@
   @Override
   public RuleKey.Builder appendToRuleKey(RuleKey.Builder builder) throws IOException {
     super.appendToRuleKey(builder)
+        .set("exportedDeps", exportedDeps)
         .set("srcs", srcs)
         .setSourcePaths("resources", resources)
-        .set("proguard", proguardConfig)
-        .set("exportDeps", exportDeps);
+        .set("proguard", proguardConfig);
     javacOptions.appendToRuleKey(builder);
     return builder;
   }
@@ -486,8 +494,8 @@
   }
 
   @Override
-  public boolean getExportDeps() {
-    return exportDeps;
+  public ImmutableSortedSet<BuildRule> getExportedDeps() {
+    return exportedDeps;
   }
 
   /**
@@ -814,7 +822,7 @@
     protected Set<SourcePath> resources = Sets.newHashSet();
     protected final AnnotationProcessingParams.Builder annotationProcessingBuilder =
         new AnnotationProcessingParams.Builder();
-    protected boolean exportDeps = false;
+    protected Set<BuildTarget> exportedDeps = Sets.newHashSet();
     protected JavacOptions.Builder javacOptions = JavacOptions.builder();
     protected Optional<String> proguardConfig = Optional.absent();
 
@@ -834,7 +842,7 @@
           srcs,
           resources,
           proguardConfig,
-          exportDeps,
+          getBuildTargetsAsBuildRules(ruleResolver, exportedDeps),
           javacOptions.build());
     }
 
@@ -889,8 +897,8 @@
       return this;
     }
 
-    public Builder setExportDeps(boolean exportDeps) {
-      this.exportDeps = exportDeps;
+    public Builder addExportedDep(BuildTarget buildTarget) {
+      this.exportedDeps.add(buildTarget);
       return this;
     }
   }
diff --git a/src/com/facebook/buck/java/JavaLibraryBuildRuleFactory.java b/src/com/facebook/buck/java/JavaLibraryBuildRuleFactory.java
index a87440f..f66acb2 100644
--- a/src/com/facebook/buck/java/JavaLibraryBuildRuleFactory.java
+++ b/src/com/facebook/buck/java/JavaLibraryBuildRuleFactory.java
@@ -42,8 +42,10 @@
         proguardConfig.transform(params.getResolveFilePathRelativeToBuildFileDirectoryTransform()));
 
 
-    boolean exportDeps = params.getBooleanAttribute("export_deps");
-    builder.setExportDeps(exportDeps);
+    for (String exportedDep : params.getOptionalListAttribute("exported_deps")) {
+      BuildTarget buildTarget = params.resolveBuildTarget(exportedDep);
+      builder.addExportedDep(buildTarget);
+    }
 
     extractAnnotationProcessorParameters(
         builder.getAnnotationProcessingBuilder(), builder, params);
diff --git a/src/com/facebook/buck/java/JavaTestRule.java b/src/com/facebook/buck/java/JavaTestRule.java
index 4c4c049..dc091d8 100644
--- a/src/com/facebook/buck/java/JavaTestRule.java
+++ b/src/com/facebook/buck/java/JavaTestRule.java
@@ -91,7 +91,7 @@
         srcs,
         resources,
         proguardConfig,
-        /* exportDeps */ false,
+        /* exportDeps */ ImmutableSortedSet.<BuildRule>of(),
         javacOptions);
     this.vmArgs = ImmutableList.copyOf(vmArgs);
     this.sourceUnderTest = Preconditions.checkNotNull(sourceUnderTest);
diff --git a/src/com/facebook/buck/java/Keystore.java b/src/com/facebook/buck/java/Keystore.java
index 98440be..fc78c9c 100644
--- a/src/com/facebook/buck/java/Keystore.java
+++ b/src/com/facebook/buck/java/Keystore.java
@@ -79,7 +79,7 @@
   @Override
   public List<Step> getBuildSteps(BuildContext context, BuildableContext buildableContext)
       throws IOException {
-    // Nothing to build: this is like a glorified export_deps() rule.
+    // Nothing to build: this is like a glorified exported_deps() rule.
     return ImmutableList.of();
   }
 
diff --git a/src/com/facebook/buck/java/PrebuiltJarRule.java b/src/com/facebook/buck/java/PrebuiltJarRule.java
index 3deb3a2..003648e 100644
--- a/src/com/facebook/buck/java/PrebuiltJarRule.java
+++ b/src/com/facebook/buck/java/PrebuiltJarRule.java
@@ -25,12 +25,14 @@
 import com.facebook.buck.rules.AbstractBuildRuleBuilderParams;
 import com.facebook.buck.rules.AnnotationProcessingData;
 import com.facebook.buck.rules.BuildContext;
+import com.facebook.buck.rules.BuildRule;
 import com.facebook.buck.rules.BuildRuleParams;
 import com.facebook.buck.rules.BuildRuleResolver;
 import com.facebook.buck.rules.BuildRuleType;
 import com.facebook.buck.rules.BuildableContext;
 import com.facebook.buck.rules.BuildableProperties;
 import com.facebook.buck.rules.DoNotUseAbstractBuildable;
+import com.facebook.buck.rules.ExportDependencies;
 import com.facebook.buck.rules.OnDiskBuildInfo;
 import com.facebook.buck.rules.RuleKey;
 import com.facebook.buck.rules.Sha1HashCode;
@@ -62,7 +64,7 @@
  * A rule that establishes a pre-compiled JAR file as a dependency.
  */
 public class PrebuiltJarRule extends DoNotUseAbstractBuildable
-    implements JavaLibraryRule, HasClasspathEntries {
+    implements JavaLibraryRule, HasClasspathEntries, ExportDependencies {
 
   private final static BuildableProperties OUTPUT_TYPE = new BuildableProperties(LIBRARY);
 
@@ -187,6 +189,11 @@
   }
 
   @Override
+  public ImmutableSortedSet<BuildRule> getExportedDeps() {
+    return getDeps();
+  }
+
+  @Override
   public AnnotationProcessingData getAnnotationProcessingData() {
     return AnnotationProcessingData.EMPTY;
   }
diff --git a/src/com/facebook/buck/parser/buck.py b/src/com/facebook/buck/parser/buck.py
index 46b8719..71b144a 100644
--- a/src/com/facebook/buck/parser/buck.py
+++ b/src/com/facebook/buck/parser/buck.py
@@ -210,7 +210,8 @@
     name,
     srcs=[],
     resources=[],
-    export_deps=False,
+    export_deps=None,
+    exported_deps=[],
     source='6',
     target='6',
     proguard_config=None,
@@ -222,11 +223,12 @@
     'name' : name,
     'srcs' : srcs,
     'resources' : resources,
-    'export_deps' : export_deps,
+    # Temporary hack to let repos cut over to new style of exporting deps.
+    'exported_deps' : deps if export_deps else exported_deps,
     'source' : source,
     'target' : target,
     'proguard_config' : proguard_config,
-    'deps' : deps,
+    'deps' : deps + exported_deps,
     'visibility' : visibility,
   }, build_env)
 
diff --git a/src/com/facebook/buck/rules/AbstractBuildRule.java b/src/com/facebook/buck/rules/AbstractBuildRule.java
index 88eeb8e..5e71344 100644
--- a/src/com/facebook/buck/rules/AbstractBuildRule.java
+++ b/src/com/facebook/buck/rules/AbstractBuildRule.java
@@ -72,11 +72,6 @@
   }
 
   @Override
-  public boolean getExportDeps() {
-    return true;
-  }
-
-  @Override
   public final ImmutableSortedSet<BuildRule> getDeps() {
     return deps;
   }
diff --git a/src/com/facebook/buck/rules/BUCK b/src/com/facebook/buck/rules/BUCK
index 5c70e41..6492cb0 100644
--- a/src/com/facebook/buck/rules/BUCK
+++ b/src/com/facebook/buck/rules/BUCK
@@ -112,6 +112,7 @@
     'DefaultBuildRuleBuilderParams.java',
     'DirArtifactCache.java',
     'DoNotUseAbstractBuildable.java',
+    'ExportDependencies.java',
     'IndividualTestEvent.java',
     'InstallableBuildRule.java',
     'LabelsAttributeBuilder.java',
diff --git a/src/com/facebook/buck/rules/BuildRule.java b/src/com/facebook/buck/rules/BuildRule.java
index ab745ff..3382e24 100644
--- a/src/com/facebook/buck/rules/BuildRule.java
+++ b/src/com/facebook/buck/rules/BuildRule.java
@@ -88,11 +88,6 @@
   public BuildRuleSuccess.Type getBuildResultType();
 
   /**
-   * @return whether or not this rule exports its dependencies to all rules depending on it.
-   */
-  public boolean getExportDeps();
-
-  /**
    * @return key based on the BuildRule's state, including the transitive closure of its
    *     dependencies' keys.
    */
diff --git a/src/com/facebook/buck/rules/ExportDependencies.java b/src/com/facebook/buck/rules/ExportDependencies.java
new file mode 100644
index 0000000..c00d401
--- /dev/null
+++ b/src/com/facebook/buck/rules/ExportDependencies.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013-present Facebook, 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.facebook.buck.rules;
+
+import com.google.common.collect.ImmutableSortedSet;
+
+/**
+ * {@link BuildRule} that can export a subset of it's dependencies.
+ */
+public interface ExportDependencies {
+  public ImmutableSortedSet<BuildRule> getExportedDeps();
+}
diff --git a/test/com/facebook/buck/cli/AuditOwnerCommandTest.java b/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
index 044e41e..19fafd4 100644
--- a/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
+++ b/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
@@ -128,11 +128,6 @@
     }
 
     @Override
-    public boolean getExportDeps() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
     public final RuleKey getRuleKey() {
       throw new UnsupportedOperationException();
     }
diff --git a/test/com/facebook/buck/command/ProjectTest.java b/test/com/facebook/buck/command/ProjectTest.java
index 0ff32a8..16ef4cd 100644
--- a/test/com/facebook/buck/command/ProjectTest.java
+++ b/test/com/facebook/buck/command/ProjectTest.java
@@ -140,7 +140,7 @@
             "//java/src/com/facebook/exportlib:exportlib"))
         .addSrc("ExportLib.java")
         .addDep(BuildTargetFactory.newInstance("//third_party/guava:guava"))
-        .setExportDeps(true)
+        .addExportedDep(BuildTargetFactory.newInstance("//third_party/guava:guava"))
         .addVisibilityPattern(BuildTargetPattern.MATCH_ALL));
 
     // android_library //java/src/com/facebook/base:base
diff --git a/test/com/facebook/buck/java/DefaultJavaLibraryRuleIntegrationTest.java b/test/com/facebook/buck/java/DefaultJavaLibraryRuleIntegrationTest.java
index e720892..2f5d550 100644
--- a/test/com/facebook/buck/java/DefaultJavaLibraryRuleIntegrationTest.java
+++ b/test/com/facebook/buck/java/DefaultJavaLibraryRuleIntegrationTest.java
@@ -171,9 +171,11 @@
       "Rule //:raz builds with its transitive dependencies but not with its first order " +
           "dependencies.",
       "The following packages were missing:",
+      "Blargh",
       "Meh",
       "Try adding the following deps:",
-      "//:foo");
+      "//:foo",
+      "//:blargh");
 
     buildResult.assertExitCode("Build should have succeeded with warnings.", 0);
 
diff --git a/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java b/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java
index e6ec316..44ec6e5 100644
--- a/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java
+++ b/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java
@@ -143,7 +143,7 @@
             new FileSourcePath("android/java/src/com/facebook/common/util/data.json")
         ),
         /* proguardConfig */ Optional.<String>absent(),
-        /* exportDeps */ false,
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(),
         JavacOptions.DEFAULTS
         );
 
@@ -176,7 +176,7 @@
             new FileSourcePath("android/java/src/com/facebook/common/util/data.json")
         ),
         /* proguargConfig */ Optional.<String>absent(),
-        /* exportDeps */ false,
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(),
         JavacOptions.DEFAULTS
         );
 
@@ -210,7 +210,7 @@
             new FileSourcePath("android/java/src/com/facebook/common/util/data.json")
         ),
         /* proguargConfig */ Optional.<String>absent(),
-        /* exportDeps */ false,
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(),
         JavacOptions.DEFAULTS);
 
     ImmutableList.Builder<Step> commands = ImmutableList.builder();
@@ -543,13 +543,28 @@
   }
 
   @Test
-  public void testExportDeps() {
+  public void testExportedDeps() {
     BuildRuleResolver ruleResolver = new BuildRuleResolver();
 
+    BuildTarget nonIncludedTarget = BuildTargetFactory.newInstance("//:not_included");
+    JavaLibraryRule notIncluded = ruleResolver.buildAndAddToIndex(
+        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
+            .setBuildTarget(nonIncludedTarget)
+            .addSrc("java/src/com/not_included/Raz.java"));
+
+    BuildTarget includedTarget = BuildTargetFactory.newInstance("//:included");
+    JavaLibraryRule included = ruleResolver.buildAndAddToIndex(
+        DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
+            .setBuildTarget(includedTarget)
+            .addSrc("java/src/com/included/Rofl.java"));
+
     BuildTarget libraryOneTarget = BuildTargetFactory.newInstance("//:libone");
     JavaLibraryRule libraryOne = ruleResolver.buildAndAddToIndex(
         DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
         .setBuildTarget(libraryOneTarget)
+        .addDep(BuildTargetFactory.newInstance("//:not_included"))
+        .addDep(BuildTargetFactory.newInstance("//:included"))
+        .addExportedDep(BuildTargetFactory.newInstance("//:included"))
         .addSrc("java/src/com/libone/Bar.java"));
 
     BuildTarget libraryTwoTarget = BuildTargetFactory.newInstance("//:libtwo");
@@ -558,7 +573,7 @@
         .setBuildTarget(libraryTwoTarget)
         .addSrc("java/src/com/libtwo/Foo.java")
         .addDep(BuildTargetFactory.newInstance("//:libone"))
-        .setExportDeps(true));
+        .addExportedDep(BuildTargetFactory.newInstance("//:libone")));
 
     BuildTarget parentTarget = BuildTargetFactory.newInstance("//:parent");
     JavaLibraryRule parent = ruleResolver.buildAndAddToIndex(
@@ -571,7 +586,21 @@
         "A java_library that depends on //:libone should include only libone.jar in its " +
             "classpath when compiling itself.",
         ImmutableSetMultimap.builder()
+            .put(notIncluded, "buck-out/gen/lib__not_included__output/not_included.jar")
+            .build(),
+        notIncluded.getOutputClasspathEntries());
+
+    assertEquals(
+        ImmutableSetMultimap.builder()
+            .put(included, "buck-out/gen/lib__included__output/included.jar")
+            .build(),
+        included.getOutputClasspathEntries());
+
+    assertEquals(
+        ImmutableSetMultimap.builder()
+            .put(included, "buck-out/gen/lib__included__output/included.jar")
             .put(libraryOne, "buck-out/gen/lib__libone__output/libone.jar")
+            .put(libraryOne, "buck-out/gen/lib__included__output/included.jar")
             .build(),
         libraryOne.getOutputClasspathEntries());
 
@@ -580,25 +609,23 @@
             "both libone.jar and libtwo.jar in its classpath when compiling itself.",
         ImmutableSetMultimap.builder()
             .put(libraryOne, "buck-out/gen/lib__libone__output/libone.jar")
+            .put(libraryOne, "buck-out/gen/lib__included__output/included.jar")
             .put(libraryTwo, "buck-out/gen/lib__libone__output/libone.jar")
             .put(libraryTwo, "buck-out/gen/lib__libtwo__output/libtwo.jar")
+            .put(libraryTwo, "buck-out/gen/lib__included__output/included.jar")
             .build(),
         libraryTwo.getOutputClasspathEntries());
 
     assertEquals(
-        "//:libtwo exports its deps, so both libone.jar and libtwo.jar should be on the classpath" +
-            " when compiling //:parent.",
-        ImmutableSetMultimap.builder()
-            .put(libraryTwo, "buck-out/gen/lib__libone__output/libone.jar")
-            .put(libraryTwo, "buck-out/gen/lib__libtwo__output/libtwo.jar")
-            .build(),
-        parent.getDeclaredClasspathEntries());
-
-    assertEquals(
         "A java_binary that depends on //:parent should include libone.jar, libtwo.jar and " +
             "parent.jar.",
         ImmutableSetMultimap.builder()
+            .put(included, "buck-out/gen/lib__included__output/included.jar")
+            .put(notIncluded, "buck-out/gen/lib__not_included__output/not_included.jar")
+            .put(libraryOne, "buck-out/gen/lib__included__output/included.jar")
             .put(libraryOne, "buck-out/gen/lib__libone__output/libone.jar")
+            .put(libraryTwo, "buck-out/gen/lib__included__output/included.jar")
+            .put(libraryTwo, "buck-out/gen/lib__not_included__output/not_included.jar")
             .put(libraryTwo, "buck-out/gen/lib__libone__output/libone.jar")
             .put(libraryTwo, "buck-out/gen/lib__libtwo__output/libtwo.jar")
             .put(parent, "buck-out/gen/lib__parent__output/parent.jar")
@@ -618,7 +645,7 @@
    * @see DefaultJavaLibraryRule#getAbiKeyForDeps()
    */
   @Test
-  public void testGetAbiKeyForDepsInThePresenceOfExportDeps() throws IOException {
+  public void testGetAbiKeyForDepsInThePresenceOfExportedDeps() throws IOException {
     // Create a java_library named //:tinylib with a hardcoded ABI key.
     String tinyLibAbiKeyHash = Strings.repeat("a", 40);
     JavaLibraryRule tinyLibrary = createDefaultJavaLibaryRuleWithAbiKey(
@@ -627,7 +654,7 @@
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(),
-        /* exportDeps */ false);
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of());
 
     // Create two java_library rules, each of which depends on //:tinylib, but only one of which
     // exports its deps.
@@ -637,13 +664,13 @@
         BuildTargetFactory.newInstance("//:common_with_export"),
         /* srcs */ ImmutableSet.<String>of(),
         /* deps */ ImmutableSet.<BuildRule>of(tinyLibrary),
-        /* exportDeps */ true);
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(tinyLibrary));
     DefaultJavaLibraryRule commonNoExport = createDefaultJavaLibaryRuleWithAbiKey(
         /* abiHash */ null,
         BuildTargetFactory.newInstance("//:common_no_export"),
         /* srcs */ ImmutableSet.<String>of(),
         /* deps */ ImmutableSet.<BuildRule>of(tinyLibrary),
-        /* exportDeps */ false);
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of());
 
     // Verify getAbiKeyForDeps() for the two //:common_XXX rules.
     assertEquals(
@@ -679,7 +706,7 @@
         consumerNoExport.getAbiKeyForDeps());
     assertThat(
         "Although //:consumer_no_export and //:consumer_with_export have the same deps, " +
-        "the ABIs of their deps will differ because of the use of export_deps=True.",
+        "the ABIs of their deps will differ because of the use of exported_deps is non-empty",
         consumerNoExport.getAbiKeyForDeps(),
         not(equalTo(consumerWithExport.getAbiKeyForDeps())));
     String expectedAbiKeyNoDepsHashForConsumerWithExport = Hashing.sha1().newHasher()
@@ -699,7 +726,7 @@
    * @see DefaultJavaLibraryRule#getAbiKey()
    */
   @Test
-  public void testGetAbiKeyInThePresenceOfExportDeps() throws IOException {
+  public void testGetAbiKeyInThePresenceOfExportedDeps() throws IOException {
     // Create a java_library named //:commonlib with a hardcoded ABI key.
     String commonLibAbiKeyHash = Strings.repeat("a", 40);
     JavaLibraryRule commonLibrary = createDefaultJavaLibaryRuleWithAbiKey(
@@ -708,7 +735,7 @@
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(),
-        /* exportDeps */ false);
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of());
 
     // Create two java_library rules, each of which depends on //:commonlib, but only one of which
     // exports its deps.
@@ -718,14 +745,14 @@
         BuildTargetFactory.newInstance("//:lib_with_export"),
         /* srcs */ ImmutableSet.<String>of(),
         /* deps */ ImmutableSet.<BuildRule>of(commonLibrary),
-        /* exportDeps */ true);
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(commonLibrary));
     String libNoExportAbiKeyHash = Strings.repeat("c", 40);
     DefaultJavaLibraryRule libNoExport = createDefaultJavaLibaryRuleWithAbiKey(
         /* abiHash */ libNoExportAbiKeyHash,
         BuildTargetFactory.newInstance("//:lib_no_export"),
         /* srcs */ ImmutableSet.<String>of(),
         /* deps */ ImmutableSet.<BuildRule>of(commonLibrary),
-        /* exportDeps */ false);
+        /* exportedDeps */ ImmutableSortedSet.<BuildRule>of());
 
     // Verify getAbiKey() for the two //:lib_XXX rules.
     String expectedLibWithExportAbiKeyHash = Hashing.sha1().newHasher()
@@ -748,7 +775,7 @@
    * @see DefaultJavaLibraryRule#getAbiKey()
    */
   @Test
-  public void testGetAbiKeyRecursiveExportDeps() throws IOException {
+  public void testGetAbiKeyRecursiveExportedDeps() throws IOException {
     String libAAbiKeyHash = Strings.repeat("a", 40);
     String libBAbiKeyHash = Strings.repeat("b", 40);
     String libCAbiKeyHash = Strings.repeat("c", 40);
@@ -762,28 +789,28 @@
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(),
-        /* exportDeps */ true);
+        /* exporedtDeps */ ImmutableSet.<BuildRule>of());
     JavaLibraryRule libC = createDefaultJavaLibaryRuleWithAbiKey(
         libCAbiKeyHash,
         BuildTargetFactory.newInstance("//:lib_c"),
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(libD),
-        /* exportDeps */ true);
+        /* exporedtDeps */ ImmutableSet.<BuildRule>of(libD));
     JavaLibraryRule libB = createDefaultJavaLibaryRuleWithAbiKey(
         libBAbiKeyHash,
         BuildTargetFactory.newInstance("//:lib_b"),
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(libC),
-        /* exportDeps */ true);
+        /* exportedDeps */ ImmutableSet.<BuildRule>of(libC));
     JavaLibraryRule libA = createDefaultJavaLibaryRuleWithAbiKey(
         libAAbiKeyHash,
         BuildTargetFactory.newInstance("//:lib_a"),
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(libB),
-        /* exportDeps */ true);
+        /* exportedDeps */ ImmutableSet.<BuildRule>of(libB));
 
     assertEquals(
         "If a rule has no dependencies its final ABI key should be the rule's own ABI key.",
@@ -814,7 +841,6 @@
     String expectedLibAAbiKeyHash = Hashing.sha1().newHasher()
         .putUnencodedChars(expectedLibBAbiKeyHash)
         .putUnencodedChars(expectedLibCAbiKeyHash)
-        .putUnencodedChars(libDAbiKeyHash)
         .putUnencodedChars(libAAbiKeyHash)
         .hash()
         .toString();
@@ -831,28 +857,28 @@
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(),
-        /* exportDeps */ false);
+        /* exportedDeps */ ImmutableSet.<BuildRule>of());
     libC = createDefaultJavaLibaryRuleWithAbiKey(
         libCAbiKeyHash,
         BuildTargetFactory.newInstance("//:lib_c2"),
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(libD),
-        /* exportDeps */ false);
+        /* exportDeps */ ImmutableSet.<BuildRule>of());
     libB = createDefaultJavaLibaryRuleWithAbiKey(
         libBAbiKeyHash,
         BuildTargetFactory.newInstance("//:lib_b2"),
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(libC),
-        /* exportDeps */ true);
+        /* exportedDeps */ ImmutableSet.<BuildRule>of(libC));
     libA = createDefaultJavaLibaryRuleWithAbiKey(
         libAAbiKeyHash,
         BuildTargetFactory.newInstance("//:lib_a2"),
         // Must have a source file or else its ABI will be AbiWriterProtocol.EMPTY_ABI_KEY.
         /* srcs */ ImmutableSet.of("foo/Bar.java"),
         /* deps */ ImmutableSet.<BuildRule>of(libB),
-        /* exportDeps */ true);
+        /* exportedDeps */ ImmutableSet.<BuildRule>of(libB));
 
     assertEquals(
         "If export_deps is false, the final ABI key should be the rule's own ABI key.",
@@ -877,7 +903,6 @@
     expectedLibAAbiKeyHash = Hashing.sha1().newHasher()
         .putUnencodedChars(expectedLibBAbiKeyHash)
         .putUnencodedChars(libCAbiKeyHash)
-        .putUnencodedChars(libDAbiKeyHash)
         .putUnencodedChars(libAAbiKeyHash)
         .hash()
         .toString();
@@ -893,13 +918,13 @@
       BuildTarget buildTarget,
       ImmutableSet<String> srcs,
       ImmutableSet<BuildRule> deps,
-      boolean exportDeps) {
+      ImmutableSet<BuildRule> exportedDeps) {
     return new DefaultJavaLibraryRule(
         new FakeBuildRuleParams(buildTarget, ImmutableSortedSet.copyOf(deps)),
         srcs,
         /* resources */ ImmutableSet.<SourcePath>of(),
         /* proguardConfig */ Optional.<String>absent(),
-        exportDeps,
+        exportedDeps,
         JavacOptions.builder().build()
         ) {
       @Override
@@ -1106,7 +1131,7 @@
             ImmutableSet.<String>of("MyClass.java"),
             ImmutableSet.<SourcePath>of(),
             Optional.of("MyProguardConfig"),
-            /* exportDeps */ false,
+            /* exportedDeps */ ImmutableSet.<BuildRule>of(),
             JavacOptions.DEFAULTS);
       }
     };
diff --git a/test/com/facebook/buck/java/FakeDefaultJavaLibraryRule.java b/test/com/facebook/buck/java/FakeDefaultJavaLibraryRule.java
index cfafdbd..79d7885 100644
--- a/test/com/facebook/buck/java/FakeDefaultJavaLibraryRule.java
+++ b/test/com/facebook/buck/java/FakeDefaultJavaLibraryRule.java
@@ -16,6 +16,7 @@
 
 package com.facebook.buck.java;
 
+import com.facebook.buck.rules.BuildRule;
 import com.facebook.buck.rules.BuildRuleParams;
 import com.facebook.buck.rules.BuildRuleResolver;
 import com.facebook.buck.rules.FakeAbstractBuildRuleBuilderParams;
@@ -35,13 +36,13 @@
                                        Set<SourcePath> resources,
                                        Optional<String> proguardConfig,
                                        AnnotationProcessingParams annotationProcessingParams,
-                                       boolean exportDeps,
+                                       Set<BuildRule> exportedDeps,
                                        boolean ruleInputsAreCached) {
     super(buildRuleParams,
         srcs,
         resources,
         proguardConfig,
-        exportDeps,
+        exportedDeps,
         JavacOptions.builder().setAnnotationProcessingData(annotationProcessingParams).build()
     );
 
@@ -71,7 +72,7 @@
           resources,
           proguardConfig,
           processingParams,
-          exportDeps,
+          getBuildTargetsAsBuildRules(ruleResolver, exportedDeps),
           ruleInputsAreCached);
     }
 
diff --git a/test/com/facebook/buck/java/testdata/warn_on_transitive/BUCK b/test/com/facebook/buck/java/testdata/warn_on_transitive/BUCK
index 1978a26..a8bfa9e 100644
--- a/test/com/facebook/buck/java/testdata/warn_on_transitive/BUCK
+++ b/test/com/facebook/buck/java/testdata/warn_on_transitive/BUCK
@@ -3,6 +3,11 @@
 # with some hard-coded Java source code into a single library.
 
 java_library(
+  name = 'blargh',
+  srcs = ['Blargh.java'],
+)
+
+java_library(
   name = 'meh',
   srcs = ['Meh.java'],
 )
@@ -10,14 +15,21 @@
 java_library(
   name = 'foo',
   srcs = ['Foo.java'],
-  export_deps = True,
-  deps = [':meh']
+  exported_deps = [
+    ':meh'
+  ],
+  deps = [
+    ':blargh',
+  ]
 )
 
 java_library(
   name = 'bar',
   srcs = ['Bar.java'],
-  deps = [':foo'],
+  deps = [
+    ':foo', 
+    ':blargh'
+  ],
 )
 
 java_library(
diff --git a/test/com/facebook/buck/java/testdata/warn_on_transitive/Blargh.java b/test/com/facebook/buck/java/testdata/warn_on_transitive/Blargh.java
new file mode 100644
index 0000000..8469ca1
--- /dev/null
+++ b/test/com/facebook/buck/java/testdata/warn_on_transitive/Blargh.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013-present Facebook, 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.example;
+
+public class Blargh {}
diff --git a/test/com/facebook/buck/java/testdata/warn_on_transitive/Foo.java b/test/com/facebook/buck/java/testdata/warn_on_transitive/Foo.java
index 6682e61..8899454 100644
--- a/test/com/facebook/buck/java/testdata/warn_on_transitive/Foo.java
+++ b/test/com/facebook/buck/java/testdata/warn_on_transitive/Foo.java
@@ -17,5 +17,5 @@
 package com.example;
 
 public class Foo {
-  private Meh meh;  
+  private Meh meh;
 }
diff --git a/test/com/facebook/buck/java/testdata/warn_on_transitive/Raz.java b/test/com/facebook/buck/java/testdata/warn_on_transitive/Raz.java
index 95691e2..f58bca6 100644
--- a/test/com/facebook/buck/java/testdata/warn_on_transitive/Raz.java
+++ b/test/com/facebook/buck/java/testdata/warn_on_transitive/Raz.java
@@ -19,4 +19,5 @@
 public class Raz {
   private Bar bar;
   private Meh meh;
+  private Blargh blargh;
 }
diff --git a/testdata/com/facebook/buck/cli/TargetsCommandTestBuckJson1.js b/testdata/com/facebook/buck/cli/TargetsCommandTestBuckJson1.js
index 263363a..d6fd923 100644
--- a/testdata/com/facebook/buck/cli/TargetsCommandTestBuckJson1.js
+++ b/testdata/com/facebook/buck/cli/TargetsCommandTestBuckJson1.js
@@ -3,7 +3,7 @@
   "buck.output_file" : "{$OUTPUT_FILE}",
   "buck.base_path" : "testdata/com/facebook/buck/cli",
   "deps" : [ ],
-  "export_deps": false,
+  "exported_deps": [],
   "name" : "test-library",
   "proguard_config" : null, 
   "resources" : [ ],
diff --git a/third-party/java/jetty/BUCK b/third-party/java/jetty/BUCK
index cb78886..11d338b 100644
--- a/third-party/java/jetty/BUCK
+++ b/third-party/java/jetty/BUCK
@@ -10,8 +10,8 @@
 
 java_library(
   name = 'jetty',
-  export_deps = True,
-  deps = [
+  deps = [],
+  exported_deps = [
     ':jetty-all',
     ':servlet-api',
   ],
diff --git a/third-party/java/neo4j/BUCK b/third-party/java/neo4j/BUCK
index ee2ea6d..adda052 100644
--- a/third-party/java/neo4j/BUCK
+++ b/third-party/java/neo4j/BUCK
@@ -20,8 +20,8 @@
 
 java_library(
   name = 'neo4j',
-  export_deps = True,
-  deps = [
+  deps = [],
+  exported_deps = [
     ':geronimo-jta',
     ':lucene-core',
     ':neo4j-kernel',