diff --git a/bench/Bench.hs b/bench/Bench.hs
--- a/bench/Bench.hs
+++ b/bench/Bench.hs
@@ -1,7 +1,10 @@
 module Main where
 
+import           Control.Arrow
 import           Criterion.Main
 import           Data.Dependency
+import qualified Data.Map        as M
+import qualified Data.Set        as S
 
 microlens :: Dependency
 microlens = Dependency "microlens" mempty mempty
@@ -21,12 +24,18 @@
 deps :: [Dependency]
 deps = [free, lens, comonad]
 
+mapSingles :: [(d, b)] -> [(d, S.Set b)]
+mapSingles = fmap (second S.singleton)
+
+set :: PackageSet Dependency
+set = PackageSet $ M.fromList (mapSingles [("lens", lens), ("comonad", comonad), ("free", free)])
+
 main :: IO ()
 main =
     defaultMain [ bgroup "buildSequence"
-                      [ bench "3" $ nf buildSequence deps ]
-                , bgroup "asGraph"
-                      [ bench "3" $ nf (fst . asGraph) deps
-                      , bench "6" $ nf (fst . asGraph) (bifunctors : microlens : deps)
+                      [ bench "3" $ nf buildSequence deps
+                      , bench "6" $ nf buildSequence (bifunctors : microlens : deps)
                       ]
+                , bgroup "resolveDependencies"
+                      [ bench "3" $ nf (resolveDependencies set) (buildSequence [lens]) ]
                 ]
diff --git a/dependency.cabal b/dependency.cabal
--- a/dependency.cabal
+++ b/dependency.cabal
@@ -1,5 +1,5 @@
 name:                dependency
-version:             0.1.0.1
+version:             0.1.0.2
 synopsis:            Dependency resolution for package management
 description:         A library for resolving dependencies; uses a topological sort to construct a build plan and then allows choice between all compatible plans.
 license:             BSD3
@@ -45,6 +45,7 @@
   build-depends:       base
                      , dependency
                      , hspec
+                     , containers
   if flag(development)
     ghc-options:       -Werror
   if impl(ghc >= 8.0)
@@ -58,6 +59,7 @@
   main-is:             Bench.hs
   build-depends:       base
                      , dependency
+                     , containers
                      , criterion
   if flag(development)
     ghc-options:       -Werror
diff --git a/src/Data/Dependency.hs b/src/Data/Dependency.hs
--- a/src/Data/Dependency.hs
+++ b/src/Data/Dependency.hs
@@ -10,18 +10,19 @@
     , Version (..)
     ) where
 
+import           Control.Monad
 import           Data.Dependency.Sort
 import           Data.Dependency.Type
 import           Data.List            (groupBy)
 import qualified Data.Map             as M
 import qualified Data.Set             as S
 
-isPresent :: PackageSet -> Dependency -> Bool
+isPresent :: PackageSet Version -> Dependency -> Bool
 isPresent (PackageSet ps) (Dependency ln _ _) = g (M.lookup ln ps)
     where g (Just x) = not (S.null x)
           g Nothing  = False
 
-latest :: PackageSet -> Dependency -> Maybe (String, Version)
+latest :: (Ord a) => PackageSet a -> Dependency -> Maybe (String, a)
 latest (PackageSet ps) (Dependency ln _ _) = do
     s <- M.lookup ln ps
     (,) ln <$> S.lookupMax s
@@ -30,6 +31,12 @@
 buildSequence = reverse . groupBy independent . sortDeps
     where independent (Dependency ln _ ls) (Dependency ln' _ ls') = ln' `notElem` ls && ln `notElem` ls'
 
+saturateDeps :: PackageSet Dependency -> Dependency -> Maybe [Dependency]
+saturateDeps (PackageSet ps) dep = do
+    let libDeps = _libDependencies dep
+    deps <- sequence [ M.lookup lib ps | lib <- libDeps ]
+    (:) dep <$> traverse S.lookupMax deps
+
 -- | Heuristics:
 --
 -- 1. Always use a newer version when possible
@@ -43,5 +50,8 @@
 -- 5. Specify an error if a package is not present.
 --
 -- This doesn't do any package resolution beyond versioning.
-resolveDependencies :: PackageSet -> [[Dependency]] -> Maybe [[(String, Version)]]
-resolveDependencies ps sd = sequence (traverse (latest ps) <$> sd)
+resolveDependencies :: PackageSet Dependency -> [[Dependency]] -> Maybe [[Dependency]]
+resolveDependencies ps = select . getLatest <=< fmap buildSequence . saturated
+    where select = fmap (fmap (fmap snd))
+          saturated dep = join . join <$> traverse (traverse (saturateDeps ps)) dep
+          getLatest = sequence . fmap (traverse (latest ps))
diff --git a/src/Data/Dependency/Type.hs b/src/Data/Dependency/Type.hs
--- a/src/Data/Dependency/Type.hs
+++ b/src/Data/Dependency/Type.hs
@@ -31,7 +31,7 @@
 import           GHC.Generics                 (Generic)
 import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>), (<>))
 
-newtype PackageSet = PackageSet (M.Map String (S.Set Version))
+newtype PackageSet a = PackageSet (M.Map String (S.Set a))
     deriving (Eq, Ord, Generic)
     deriving newtype Binary
 
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,4 +1,7 @@
+import           Control.Arrow
 import           Data.Dependency
+import qualified Data.Map        as M
+import qualified Data.Set        as S
 import           Test.Hspec
 
 free :: Dependency
@@ -13,8 +16,17 @@
 deps :: [Dependency]
 deps = [free, lens, comonad]
 
+mapSingles :: [(d, b)] -> [(d, S.Set b)]
+mapSingles = fmap (second S.singleton)
+
+set :: PackageSet Dependency
+set = PackageSet $ M.fromList (mapSingles [("lens", lens), ("comonad", comonad), ("free", free)])
+
 main :: IO ()
-main = hspec $ parallel $
+main = hspec $ parallel $ do
     describe "buildSequence" $
         it "correctly orders dependencies" $
             buildSequence deps `shouldBe` [[free, comonad], [lens]]
+    describe "resolveDependencies" $
+        it "correctly resolves dependencies in a package set" $
+            resolveDependencies set (buildSequence [lens]) `shouldBe` Just [[free, comonad], [lens]]
