diff --git a/cabal-install/Distribution/Client/Dependency.hs b/cabal-install/Distribution/Client/Dependency.hs
index ad518f2af12097ada8a277c0935477708edef7c9..0560ff0f89e1bf3a06ec49e3c16e8738a044f4d5 100644
--- a/cabal-install/Distribution/Client/Dependency.hs
+++ b/cabal-install/Distribution/Client/Dependency.hs
@@ -513,12 +513,12 @@ resolveDependencies :: Platform
     --TODO: is this needed here? see dontUpgradeNonUpgradeablePackages
 resolveDependencies platform comp _solver params
   | null (depResolverTargets params)
-  = return (mkInstallPlan platform comp [])
+  = return (mkInstallPlan platform comp (depResolverIndependentGoals params) [])
 
 resolveDependencies platform comp  solver params =
 
     Step (debugDepResolverParams finalparams)
-  $ fmap (mkInstallPlan platform comp)
+  $ fmap (mkInstallPlan platform comp indGoals)
   $ runSolver solver (SolverConfig reorderGoals indGoals noReinstalls
                       shadowing strFlags maxBkjumps)
                      platform comp installedPkgIndex sourcePkgIndex
@@ -553,10 +553,11 @@ resolveDependencies platform comp  solver params =
 --
 mkInstallPlan :: Platform
               -> CompilerInfo
+              -> Bool
               -> [InstallPlan.PlanPackage] -> InstallPlan
-mkInstallPlan platform comp pkgIndex =
+mkInstallPlan platform comp indepGoals pkgIndex =
   let index = InstalledPackageIndex.fromList pkgIndex in
-  case InstallPlan.new platform comp index of
+  case InstallPlan.new platform comp indepGoals index of
     Right plan     -> plan
     Left  problems -> error $ unlines $
         "internal error: could not construct a valid install plan."
diff --git a/cabal-install/Distribution/Client/Dependency/Modular/ConfiguredConversion.hs b/cabal-install/Distribution/Client/Dependency/Modular/ConfiguredConversion.hs
index 97d22a52d99385e85c641047fd43fb71830884b3..405c69bcdce4beb0bf344c6b9379d5bd5579fecb 100644
--- a/cabal-install/Distribution/Client/Dependency/Modular/ConfiguredConversion.hs
+++ b/cabal-install/Distribution/Client/Dependency/Modular/ConfiguredConversion.hs
@@ -13,11 +13,11 @@ import Distribution.System
 import Distribution.Client.Dependency.Modular.Configured
 import Distribution.Client.Dependency.Modular.Package
 
-mkPlan :: Platform -> CompilerInfo ->
+mkPlan :: Platform -> CompilerInfo -> Bool ->
           SI.InstalledPackageIndex -> CI.PackageIndex SourcePackage ->
           [CP QPN] -> Either [PlanProblem] InstallPlan
-mkPlan plat comp iidx sidx cps =
-  new plat comp (SI.fromList (map (convCP iidx sidx) cps))
+mkPlan plat comp indepGoals iidx sidx cps =
+  new plat comp indepGoals (SI.fromList (map (convCP iidx sidx) cps))
 
 convCP :: SI.InstalledPackageIndex -> CI.PackageIndex SourcePackage ->
           CP QPN -> PlanPackage
diff --git a/cabal-install/Distribution/Client/InstallPlan.hs b/cabal-install/Distribution/Client/InstallPlan.hs
index 741d3124702415a7235f084a04eff02c6a8e86e4..431f82635073d2c6a19dfba36d0c93073bec18b3 100644
--- a/cabal-install/Distribution/Client/InstallPlan.hs
+++ b/cabal-install/Distribution/Client/InstallPlan.hs
@@ -188,19 +188,24 @@ instance HasInstalledPackageId PlanPackage where
   installedPackageId (Failed      pkg _) = installedPackageId pkg
 
 data InstallPlan = InstallPlan {
-    planIndex    :: PlanIndex,
-    planFakeMap  :: FakeMap,
-    planGraph    :: Graph,
-    planGraphRev :: Graph,
-    planPkgOf    :: Graph.Vertex -> PlanPackage,
-    planVertexOf :: InstalledPackageId -> Graph.Vertex,
-    planPlatform :: Platform,
-    planCompiler :: CompilerInfo
+    planIndex      :: PlanIndex,
+    planFakeMap    :: FakeMap,
+    planGraph      :: Graph,
+    planGraphRev   :: Graph,
+    planPkgOf      :: Graph.Vertex -> PlanPackage,
+    planVertexOf   :: InstalledPackageId -> Graph.Vertex,
+    planPlatform   :: Platform,
+    planCompiler   :: CompilerInfo,
+    planIndepGoals :: Bool
   }
 
 invariant :: InstallPlan -> Bool
 invariant plan =
-  valid (planPlatform plan) (planCompiler plan) (planFakeMap plan) (planIndex plan)
+    valid (planPlatform plan)
+          (planCompiler plan)
+          (planFakeMap plan)
+          (planIndepGoals plan)
+          (planIndex plan)
 
 internalError :: String -> a
 internalError msg = error $ "InstallPlan: internal error: " ++ msg
@@ -228,9 +233,9 @@ showPlanPackageTag (Failed _ _)    = "Failed"
 
 -- | Build an installation plan from a valid set of resolved packages.
 --
-new :: Platform -> CompilerInfo -> PlanIndex
+new :: Platform -> CompilerInfo -> Bool -> PlanIndex
     -> Either [PlanProblem] InstallPlan
-new platform cinfo index =
+new platform cinfo indepGoals index =
   -- NB: Need to pre-initialize the fake-map with pre-existing
   -- packages
   let isPreExisting (PreExisting _) = True
@@ -239,16 +244,17 @@ new platform cinfo index =
               . map (\p -> (fakeInstalledPackageId (packageId p), installedPackageId p))
               . filter isPreExisting
               $ PackageIndex.allPackages index in
-  case problems platform cinfo fakeMap index of
+  case problems platform cinfo fakeMap indepGoals index of
     [] -> Right InstallPlan {
-            planIndex    = index,
-            planFakeMap  = fakeMap,
-            planGraph    = graph,
-            planGraphRev = Graph.transposeG graph,
-            planPkgOf    = vertexToPkgId,
-            planVertexOf = fromMaybe noSuchPkgId . pkgIdToVertex,
-            planPlatform = platform,
-            planCompiler = cinfo
+            planIndex      = index,
+            planFakeMap    = fakeMap,
+            planGraph      = graph,
+            planGraphRev   = Graph.transposeG graph,
+            planPkgOf      = vertexToPkgId,
+            planVertexOf   = fromMaybe noSuchPkgId . pkgIdToVertex,
+            planPlatform   = platform,
+            planCompiler   = cinfo,
+            planIndepGoals = indepGoals
           }
       where (graph, vertexToPkgId, pkgIdToVertex) =
               PlanIndex.dependencyGraph fakeMap index
@@ -268,7 +274,7 @@ remove :: (PlanPackage -> Bool)
        -> InstallPlan
        -> Either [PlanProblem] InstallPlan
 remove shouldRemove plan =
-    new (planPlatform plan) (planCompiler plan) newIndex
+    new (planPlatform plan) (planCompiler plan) (planIndepGoals plan) newIndex
   where
     newIndex = PackageIndex.fromList $
                  filter (not . shouldRemove) (toList plan)
@@ -414,8 +420,9 @@ checkConfiguredPackage pkg                =
 --
 -- * if the result is @False@ use 'problems' to get a detailed list.
 --
-valid :: Platform -> CompilerInfo -> FakeMap -> PlanIndex -> Bool
-valid platform cinfo fakeMap index = null (problems platform cinfo fakeMap index)
+valid :: Platform -> CompilerInfo -> FakeMap -> Bool -> PlanIndex -> Bool
+valid platform cinfo fakeMap indepGoals index =
+    null $ problems platform cinfo fakeMap indepGoals index
 
 data PlanProblem =
      PackageInvalid       ConfiguredPackage [PackageProblem]
@@ -465,9 +472,9 @@ showPlanProblem (PackageStateInvalid pkg pkg') =
 -- error messages. This is mainly intended for debugging purposes.
 -- Use 'showPlanProblem' for a human readable explanation.
 --
-problems :: Platform -> CompilerInfo -> FakeMap
+problems :: Platform -> CompilerInfo -> FakeMap -> Bool
          -> PlanIndex -> [PlanProblem]
-problems platform cinfo fakeMap index =
+problems platform cinfo fakeMap indepGoals index =
      [ PackageInvalid pkg packageProblems
      | Configured pkg <- PackageIndex.allPackages index
      , let packageProblems = configuredPackageProblems platform cinfo pkg
@@ -480,7 +487,7 @@ problems platform cinfo fakeMap index =
      | cycleGroup <- PlanIndex.dependencyCycles fakeMap index ]
 
   ++ [ PackageInconsistency name inconsistencies
-     | (name, inconsistencies) <- PlanIndex.dependencyInconsistencies fakeMap index ]
+     | (name, inconsistencies) <- PlanIndex.dependencyInconsistencies fakeMap indepGoals index ]
 
   ++ [ PackageStateInvalid pkg pkg'
      | pkg <- PackageIndex.allPackages index
@@ -522,7 +529,7 @@ closed fakeMap = null . PlanIndex.brokenPackages fakeMap
 --   find out which packages are.
 --
 consistent :: FakeMap -> PlanIndex -> Bool
-consistent fakeMap = null . PlanIndex.dependencyInconsistencies fakeMap
+consistent fakeMap = null . PlanIndex.dependencyInconsistencies fakeMap False
 
 -- | The states of packages have that depend on each other must respect
 -- this relation. That is for very case where package @a@ depends on
diff --git a/cabal-install/Distribution/Client/PlanIndex.hs b/cabal-install/Distribution/Client/PlanIndex.hs
index b4f96e305079c3f13ba33d0c262293f2c2fa6174..4668d92033053ccf97c329966bdeabee4d33eb87 100644
--- a/cabal-install/Distribution/Client/PlanIndex.hs
+++ b/cabal-install/Distribution/Client/PlanIndex.hs
@@ -29,6 +29,7 @@ import Data.Array ((!))
 import Data.List (sortBy)
 import Data.Map (Map)
 import Data.Maybe (isNothing, fromMaybe)
+import Data.Either (lefts)
 
 #if !MIN_VERSION_base(4,8,0)
 import Data.Monoid (Monoid(..))
@@ -116,6 +117,47 @@ brokenPackages fakeMap index =
                  , isNothing (fakeLookupInstalledPackageId fakeMap index pkg') ]
   , not (null missing) ]
 
+
+dependencyInconsistencies :: forall pkg. (PackageFixedDeps pkg, HasInstalledPackageId pkg)
+                          => FakeMap
+                          -> Bool
+                          -> PackageIndex pkg
+                          -> [(PackageName, [(PackageIdentifier, Version)])]
+dependencyInconsistencies fakeMap indepGoals index  =
+    concatMap (dependencyInconsistencies' fakeMap) subplans
+  where
+    subplans :: [PackageIndex pkg]
+    subplans = lefts $
+                 map (dependencyClosure fakeMap index)
+                     (rootSets fakeMap indepGoals index)
+
+-- | Compute the root sets of a plan
+--
+-- A root set is a set of packages whose dependency closure must be consistent.
+-- This is the set of all top-level library roots (taken together normally, or
+-- as singletons sets if we are considering them as independent goals), along
+-- with all setup dependencies of all packages.
+rootSets :: (PackageFixedDeps pkg, HasInstalledPackageId pkg)
+         => FakeMap -> Bool -> PackageIndex pkg -> [[InstalledPackageId]]
+rootSets fakeMap indepGoals index =
+       if indepGoals then map (:[]) libRoots else [libRoots]
+  where
+    libRoots = libraryRoots fakeMap index
+
+-- | Compute the library roots of a plan
+--
+-- The library roots are the set of packages with no reverse dependencies
+-- (no reverse library dependencies but also no reverse setup dependencies).
+libraryRoots :: (PackageFixedDeps pkg, HasInstalledPackageId pkg)
+             => FakeMap -> PackageIndex pkg -> [InstalledPackageId]
+libraryRoots fakeMap index =
+    map (installedPackageId . toPkgId) roots
+  where
+    (graph, toPkgId, _) = dependencyGraph fakeMap index
+    indegree = Graph.indegree graph
+    roots    = filter isRoot (Graph.vertices graph)
+    isRoot v = indegree ! v == 0
+
 -- | Given a package index where we assume we want to use all the packages
 -- (use 'dependencyClosure' if you need to get such a index subset) find out
 -- if the dependencies within it use consistent versions of each package.
@@ -126,12 +168,12 @@ brokenPackages fakeMap index =
 -- depend on it and the versions they require. These are guaranteed to be
 -- distinct.
 --
-dependencyInconsistencies :: forall pkg.
-                             (PackageFixedDeps pkg, HasInstalledPackageId pkg)
-                          => FakeMap
-                          -> PackageIndex pkg
-                          -> [(PackageName, [(PackageIdentifier, Version)])]
-dependencyInconsistencies fakeMap index =
+dependencyInconsistencies' :: forall pkg.
+                              (PackageFixedDeps pkg, HasInstalledPackageId pkg)
+                           => FakeMap
+                           -> PackageIndex pkg
+                           -> [(PackageName, [(PackageIdentifier, Version)])]
+dependencyInconsistencies' fakeMap index =
     [ (name, [ (pid,packageVersion dep) | (dep,pids) <- uses, pid <- pids])
     | (name, ipid_map) <- Map.toList inverseIndex
     , let uses = Map.elems ipid_map
@@ -196,7 +238,6 @@ dependencyCycles fakeMap index =
 --
 -- * Note that if the result is @Right []@ it is because at least one of
 -- the original given 'PackageIdentifier's do not occur in the index.
---
 dependencyClosure :: (PackageFixedDeps pkg, HasInstalledPackageId pkg)
                   => FakeMap
                   -> PackageIndex pkg