diff --git a/cabal-cargs.cabal b/cabal-cargs.cabal
--- a/cabal-cargs.cabal
+++ b/cabal-cargs.cabal
@@ -1,16 +1,16 @@
 name: cabal-cargs
-version: 0.5
+version: 0.6
 cabal-version: >=1.9.2
 build-type: Simple
 license: BSD3
 license-file: LICENSE
 maintainer: daniel.trstenjak@gmail.com
 synopsis: A command line program for extracting compiler arguments from a cabal file.
-description: For further details please consult the <https://github.com/dan-t/cabal-cargs README>.
+description:
+    For further details please consult the <https://github.com/dan-t/cabal-cargs README>.
 category: Utils
 author: Daniel Trstenjak
-data-dir: ""
-extra-source-files: 
+extra-source-files:
     README.md
     tests/mkGoldens
     tests/takeOutputsAsGoldens
@@ -34,36 +34,55 @@
     location: https://github.com/dan-t/cabal-cargs
  
 library
-    build-depends: base >=3 && <5, cmdargs >=0.10.5 && <0.11,
-                   lens >=4.0.1 && <4.1, directory -any, strict >=0.3.2 && <0.4,
-                   transformers >=0.3.0.0 && <0.4, either >=4.1.1 && <4.2,
-                   text >=1.1.0.1 && <1.2, system-filepath >=0.4.9 && <0.5,
-                   system-fileio >=0.3.12 && <0.4, unordered-containers >=0.2.3.3 && <0.3,
-                   Cabal >=1.16 && <1.19
-    exposed-modules: CabalCargs.Args CabalCargs.Fields
-                     CabalCargs.Formatting CabalCargs.Format CabalCargs.Spec
-                     CabalCargs.Sections CabalCargs.CompilerArgs CabalCargs.BuildInfo
-                     CabalCargs.CondVars
+    build-depends:
+        base >=3 && <5,
+        cmdargs >=0.10.5 && <0.11,
+        lens >=4.0.1 && <4.1,
+        directory -any,
+        strict >=0.3.2 && <0.4,
+        transformers >=0.3.0.0 && <0.4,
+        either >=4.1.1 && <4.2,
+        text >=1.1.0.1 && <1.2,
+        system-filepath >=0.4.9 && <0.5,
+        system-fileio >=0.3.12 && <0.4,
+        unordered-containers >=0.2.3.3 && <0.3,
+        cabal-lenses >=0.1 && <0.2,
+        Cabal >=1.16 && <1.21
+    exposed-modules:
+        CabalCargs.Args
+        CabalCargs.Fields
+        CabalCargs.Formatting
+        CabalCargs.Format
+        CabalCargs.Spec
+        CabalCargs.CompilerArgs
     exposed: True
     buildable: True
     cpp-options: -DCABAL
     hs-source-dirs: lib
-    other-modules: Paths_cabal_cargs
+    other-modules:
+        CabalCargs.BuildInfo
+        Paths_cabal_cargs
     ghc-options: -W
  
 executable cabal-cargs
-    build-depends: base >=3 && <5, cabal-cargs -any
+    build-depends:
+        base >=3 && <5,
+        cabal-cargs -any
     main-is: Main.hs
     buildable: True
     hs-source-dirs: exe
     ghc-options: -W
-
+ 
 test-suite tests
-    build-depends: base >=3 && <5, tasty ==0.7.*,
-                   tasty-golden >=2.2.0.2 && <2.3, filepath >=1.3.0.1 && <1.4,
-                   cabal-cargs -any
+    build-depends:
+        base >=3 && <5,
+        tasty ==0.7.*,
+        tasty-golden >=2.2.0.2 && <2.3,
+        filepath >=1.3.0.1 && <1.4,
+        cabal-cargs -any
     type: exitcode-stdio-1.0
     main-is: Main.hs
     buildable: True
     hs-source-dirs: tests
     ghc-options: -W
+ 
diff --git a/lib/CabalCargs/BuildInfo.hs b/lib/CabalCargs/BuildInfo.hs
--- a/lib/CabalCargs/BuildInfo.hs
+++ b/lib/CabalCargs/BuildInfo.hs
@@ -1,161 +1,32 @@
-{-# LANGUAGE TemplateHaskell, Rank2Types, PatternGuards #-}
+{-# LANGUAGE Rank2Types, PatternGuards, TupleSections #-}
 
 module CabalCargs.BuildInfo
-   ( BuildInfo(..)
-   , buildInfosOfLib
-   , buildInfosOfExe
-   , buildInfosOfTest
-   , buildInfosOfBenchmark
-   , buildInfosOf
-   , buildInfos
-   , field
+   ( field
    ) where
 
-import qualified Distribution.PackageDescription as PD
-import Distribution.PackageDescription (GenericPackageDescription(..), CondTree(..), ConfVar)
-import Distribution.Compiler
-import Distribution.Package (Dependency(..), PackageName(..))
-import Distribution.Version (anyVersion)
-import Language.Haskell.Extension
+import Distribution.PackageDescription (BuildInfo(..))
+import Distribution.Compiler (CompilerFlavor(..))
 import Control.Lens
-import Data.List (find)
-import qualified CabalCargs.Sections as S
 import qualified CabalCargs.Fields as F
-import qualified CabalCargs.CondVars as CV
-
-
-data BuildInfo = BuildInfo
-   { buildInfo    :: PD.BuildInfo
-   , buildDepends :: [Dependency]
-   } deriving (Show, Eq)
-
-
-makeLensesFor [ ("buildInfo"   , "buildInfoL")
-              , ("buildDepends", "buildDependsL")
-              ] ''BuildInfo
-
-
-makeLensesFor [ ("hsSourceDirs"      , "hsSourceDirsL")
-              , ("options"           , "optionsL")
-              , ("defaultLanguage"   , "defaultLanguageL")
-              , ("cppOptions"        , "cppOptionsL")
-              , ("cSources"          , "cSourcesL")
-              , ("ccOptions"         , "ccOptionsL")
-              , ("extraLibDirs"      , "extraLibDirsL")
-              , ("extraLibs"         , "extraLibsL")
-              , ("ldOptions"         , "ldOptionsL")
-              , ("includeDirs"       , "includeDirsL")
-              , ("includes"          , "includesL")
-              ] ''PD.BuildInfo
-
-
-buildInfosOf :: S.Section -> CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOf S.Library           = buildInfosOfLib
-buildInfosOf (S.Executable name) = buildInfosOfExe name
-buildInfosOf (S.TestSuite name)  = buildInfosOfTest name
-buildInfosOf (S.Benchmark name)  = buildInfosOfBenchmark name
-
-
-buildInfos :: CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfos vars pkgDescrp =
-   concat [ buildInfosOfLib vars pkgDescrp
-          , buildInfosOfAllExes vars pkgDescrp
-          , buildInfosOfAllTests vars pkgDescrp
-          , buildInfosOfAllBenchmarks vars pkgDescrp
-          ]
-
-
-buildInfosOfLib :: CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOfLib vars pkgDescrp
-   | Just condLib <- condLibrary pkgDescrp
-   = map (toBuildInfo PD.libBuildInfo) $ condTreeDatasAndConstraints vars condLib
-
-   | otherwise
-   = []
-
-
-buildInfosOfExe :: String -> CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOfExe name vars pkgDescrp
-   | Just (_, condExe) <- find ((== name) . fst) $ condExecutables pkgDescrp
-   = map (toBuildInfo PD.buildInfo) $ condTreeDatasAndConstraints vars condExe
-
-   | otherwise
-   = []
-
-
-buildInfosOfAllExes :: CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOfAllExes vars pkgDescrp =
-   concat $ map ((map (toBuildInfo PD.buildInfo)) . (condTreeDatasAndConstraints vars) . snd) (condExecutables pkgDescrp)
-
-
-buildInfosOfTest :: String -> CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOfTest name vars pkgDescrp
-   | Just (_, condTest) <- find ((== name) . fst) $ condTestSuites pkgDescrp
-   = map (toBuildInfo PD.testBuildInfo) $ condTreeDatasAndConstraints vars condTest
-
-   | otherwise
-   = []
-
-
-buildInfosOfAllTests :: CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOfAllTests vars pkgDescrp =
-   concat $ map ((map (toBuildInfo PD.testBuildInfo)) . (condTreeDatasAndConstraints vars) . snd) (condTestSuites pkgDescrp)
-
-
-buildInfosOfBenchmark :: String -> CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOfBenchmark name vars pkgDescrp
-   | Just (_, condBench) <- find ((== name) . fst) $ condBenchmarks pkgDescrp
-   = map (toBuildInfo PD.benchmarkBuildInfo) $ condTreeDatasAndConstraints vars condBench
-
-   | otherwise
-   = []
-
-
-buildInfosOfAllBenchmarks :: CV.CondVars -> GenericPackageDescription -> [BuildInfo]
-buildInfosOfAllBenchmarks vars pkgDescrp =
-   concat $ map ((map (toBuildInfo PD.benchmarkBuildInfo)) . (condTreeDatasAndConstraints vars) . snd) (condBenchmarks pkgDescrp)
-
-
-toBuildInfo :: (dat -> PD.BuildInfo) -> (dat, [Dependency]) -> BuildInfo
-toBuildInfo f (dat, deps) = BuildInfo { buildInfo    = f dat
-                                      , buildDepends = deps
-                                      }
-
-
--- | Returns all 'condTreeData' and 'condTreeConstraints' of the 'CondTree' which conditions match the given 'CondVars'.
-condTreeDatasAndConstraints :: CV.CondVars -> CondTree ConfVar [Dependency] dat -> [(dat, [Dependency])]
-condTreeDatasAndConstraints vars tree = go (condTreeComponents tree) [dataAndConstraints tree]
-   where
-      go [] dats = dats
-
-      go ((cond, ifTree, elseTree) : comps) dats
-         | CV.eval vars cond
-         = go comps $ go (condTreeComponents ifTree) (dataAndConstraints ifTree : dats)
-
-         | Just tree <- elseTree
-         = go comps $ go (condTreeComponents tree) (dataAndConstraints tree : dats)
-
-         | otherwise
-         = go comps dats
-
-      dataAndConstraints tree = (condTreeData tree, condTreeConstraints tree)
+import qualified CabalLenses as CL
+import Language.Haskell.Extension (Extension(..), KnownExtension(..), Language(..))
 
 
 -- | A lens from a 'BuildInfo' to a list of stringified field entries of the 'BuildInfo'.
 field :: F.Field -> Traversal' BuildInfo [String]
-field F.Hs_Source_Dirs         = buildInfoL . hsSourceDirsL
-field F.Ghc_Options            = buildInfoL . optionsL . traversed . filtered ((== GHC) . fst) . _2
-field F.Default_Extensions     = buildInfoL . oldAndDefaultExtensionsL . extsToStrings
-field F.Default_Language       = buildInfoL . defaultLanguageL . langToString
-field F.Cpp_Options            = buildInfoL . cppOptionsL
-field F.C_Sources              = buildInfoL . cSourcesL
-field F.Cc_Options             = buildInfoL . ccOptionsL
-field F.Extra_Lib_Dirs         = buildInfoL . extraLibDirsL
-field F.Extra_Libraries        = buildInfoL . extraLibsL
-field F.Ld_Options             = buildInfoL . ldOptionsL
-field F.Include_Dirs           = buildInfoL . includeDirsL
-field F.Includes               = buildInfoL . includesL
-field F.Build_Depends          = buildDependsL . depsToStrings
+field F.Hs_Source_Dirs         = CL.hsSourceDirsL
+field F.Ghc_Options            = CL.optionsL . traversed . filtered ((== GHC) . fst) . _2
+field F.Default_Extensions     = oldAndDefaultExtensionsL . extsToStrings
+field F.Default_Language       = CL.defaultLanguageL . langToString
+field F.Cpp_Options            = CL.cppOptionsL
+field F.C_Sources              = CL.cSourcesL
+field F.Cc_Options             = CL.ccOptionsL
+field F.Extra_Lib_Dirs         = CL.extraLibDirsL
+field F.Extra_Libraries        = CL.extraLibsL
+field F.Ld_Options             = CL.ldOptionsL
+field F.Include_Dirs           = CL.includeDirsL
+field F.Includes               = CL.includesL
+field F.Build_Depends          = nopLens
 field F.Package_Db             = nopLens
 field F.Autogen_Hs_Source_Dirs = nopLens
 field F.Autogen_Include_Dirs   = nopLens
@@ -166,11 +37,11 @@
 -- | A lens that merges the fields 'default-extensions' and 'extensions',
 --   which now mean the same thing in cabal, 'extensions' is only the old
 --   name of 'default-extensions'.
-oldAndDefaultExtensionsL :: Lens' PD.BuildInfo [Extension]
+oldAndDefaultExtensionsL :: Lens' BuildInfo [Extension]
 oldAndDefaultExtensionsL = lens getter setter
    where
-      getter buildInfo      = (PD.oldExtensions buildInfo) ++ (PD.defaultExtensions buildInfo)
-      setter buildInfo exts = buildInfo { PD.defaultExtensions = exts }
+      getter buildInfo      = oldExtensions buildInfo ++ defaultExtensions buildInfo
+      setter buildInfo exts = buildInfo { defaultExtensions = exts }
 
 
 -- | An iso that converts between a list of extensions
@@ -217,15 +88,7 @@
       toLang _ = Nothing
 
 
--- | An iso that converts a list of dependencies to a list of package names
-depsToStrings :: Iso' [Dependency] [String]
-depsToStrings = iso (map toString) (map toDep)
-   where
-      toString (Dependency (PackageName name) _) = name
-      toDep name = Dependency (PackageName name) anyVersion
-
-
 -- | A lens that does nothing, always returns an empty
 --   list and doesn't modify the given BuildInfo.
 nopLens :: Lens' BuildInfo [String]
-nopLens = lens (const []) (\buildInfo _ -> buildInfo)
+nopLens = lens (const []) const
diff --git a/lib/CabalCargs/CompilerArgs.hs b/lib/CabalCargs/CompilerArgs.hs
--- a/lib/CabalCargs/CompilerArgs.hs
+++ b/lib/CabalCargs/CompilerArgs.hs
@@ -9,10 +9,11 @@
 import CabalCargs.Spec (Spec)
 import qualified CabalCargs.Spec as Spec
 import qualified CabalCargs.Args as A
-import qualified CabalCargs.Sections as S
 import qualified CabalCargs.Fields as F
 import qualified CabalCargs.BuildInfo as B
+import qualified CabalLenses as CL
 import Data.List (nub, foldl')
+import Data.Maybe (maybeToList, listToMaybe)
 import Control.Applicative ((<$>))
 import Control.Lens
 import qualified Filesystem.Path.CurrentOS as FP
@@ -75,14 +76,7 @@
 
 -- | Create a 'CompilerArgs' and collect the compiler args specified by 'Spec'.
 fromSpec :: Spec -> CompilerArgs
-fromSpec spec =
-   case Spec.sections spec of
-        S.Sections sections ->
-           absolutePaths $ foldl' collectFromSection defaultCompilerArgs sections
-
-        S.AllSections ->
-           absolutePaths $ collectFields buildInfos defaultCompilerArgs
-
+fromSpec spec = absolutePaths $ foldl' collectFromSection defaultCompilerArgs (Spec.sections spec)
    where
       absolutePaths cargs
          | Spec.relativePaths spec
@@ -102,45 +96,47 @@
             cabalDir             = FP.directory . FP.decodeString $ Spec.cabalFile spec
 
       collectFromSection cargs section =
-         collectFields (buildInfosOf section) cargs
+         foldl' addCarg cargs (Spec.fields spec)
+         where
+            addCarg cargs F.Package_Db  =
+               cargs & packageDBL .~ Spec.packageDB spec
 
-      collectFields buildInfos cargs =
-        foldl' (addCarg buildInfos) cargs (Spec.fields spec)
-        where
-           addCarg _ cargs F.Package_Db  =
-              cargs & packageDBL .~ Spec.packageDB spec
+            addCarg cargs F.Autogen_Hs_Source_Dirs
+               | Just distDir <- Spec.distDir spec
+               = cargs & autogenHsSourceDirsL .~ [distDir ++ "/build/autogen"]
 
-           addCarg _ cargs F.Autogen_Hs_Source_Dirs
-              | Just distDir <- Spec.distDir spec
-              = cargs & autogenHsSourceDirsL .~ [distDir ++ "/build/autogen"]
+               | otherwise
+               = cargs
 
-              | otherwise
-              = cargs
+            addCarg cargs F.Autogen_Include_Dirs
+               | Just distDir <- Spec.distDir spec
+               = cargs & autogenIncludeDirsL .~ [distDir ++ "/build/autogen"]
 
-           addCarg _ cargs F.Autogen_Include_Dirs
-              | Just distDir <- Spec.distDir spec
-              = cargs & autogenIncludeDirsL .~ [distDir ++ "/build/autogen"]
+               | otherwise
+               = cargs
 
-              | otherwise
-              = cargs
+            addCarg cargs F.Autogen_Includes
+               | Just _ <- Spec.distDir spec
+               = cargs & autogenIncludesL .~ ["cabal_macros.h"]
 
-           addCarg _ cargs F.Autogen_Includes
-              | Just _ <- Spec.distDir spec
-              = cargs & autogenIncludesL .~ ["cabal_macros.h"]
+               | otherwise
+               = cargs
 
-              | otherwise
-              = cargs
+            addCarg cargs F.Hdevtools_Socket =
+               cargs & hdevtoolsSocketL .~ Just ".hdevtools.sock"
 
-           addCarg _ cargs F.Hdevtools_Socket =
-              cargs & hdevtoolsSocketL .~ Just ".hdevtools.sock"
+            addCarg cargs F.Build_Depends =
+               cargs & buildDependsL %~ nub . (++ dependencies) 
 
-           addCarg buildInfos cargs field =
-              cargs & (fieldL field) %~ nub . (++ buildInfoFields)
-              where
-                 buildInfoFields = concat $ map (^. B.field field) buildInfos
+            addCarg cargs field =
+               cargs & fieldL field %~ nub . (++ buildInfoFields)
+               where
+                  buildInfoFields = concatMap (^. B.field field) buildInfos
 
-      buildInfos           = B.buildInfos (Spec.condVars spec) (Spec.cabalPackage spec)
-      buildInfosOf section = B.buildInfosOf section (Spec.condVars spec) (Spec.cabalPackage spec)
+            dependencies = pkgDescrp ^.. CL.dependencyIf condVars section . CL.depPackageName . CL.pkgNameString
+            buildInfos   = pkgDescrp ^.. CL.buildInfoIf condVars section
+            pkgDescrp    = Spec.pkgDescrp spec
+            condVars     = Spec.condVars spec
 
 
 fieldL :: F.Field -> Lens' CompilerArgs [String]
@@ -157,11 +153,15 @@
 fieldL F.Include_Dirs           = includeDirsL
 fieldL F.Includes               = includesL
 fieldL F.Build_Depends          = buildDependsL
-fieldL F.Package_Db             = error $ "Unexpected field Package_Db for CabalCargs.CompilerArgs.fieldL!"
+fieldL F.Package_Db             = packageDBL . maybeToListL
 fieldL F.Autogen_Hs_Source_Dirs = autogenHsSourceDirsL
 fieldL F.Autogen_Include_Dirs   = autogenIncludeDirsL
 fieldL F.Autogen_Includes       = autogenIncludesL
-fieldL F.Hdevtools_Socket       = error $ "Unexpected field Hdevtools_Socket for CabalCargs.CompilerArgs.fieldL!"
+fieldL F.Hdevtools_Socket       = hdevtoolsSocketL . maybeToListL
+
+
+maybeToListL :: Iso' (Maybe a) [a]
+maybeToListL = iso maybeToList listToMaybe
 
 
 defaultCompilerArgs :: CompilerArgs
diff --git a/lib/CabalCargs/CondVars.hs b/lib/CabalCargs/CondVars.hs
deleted file mode 100644
--- a/lib/CabalCargs/CondVars.hs
+++ /dev/null
@@ -1,77 +0,0 @@
-{-# Language TemplateHaskell, PatternGuards #-}
-
-module CabalCargs.CondVars
-   ( CondVars(..)
-   , fromDefaults
-   , enableFlag
-   , disableFlag
-   , eval
-   ) where
-
-import qualified Distribution.PackageDescription as PD
-import Distribution.PackageDescription (Condition(..))
-import qualified Distribution.System as S
-import Distribution.System (OS(..), Arch(..))
-import qualified Data.HashMap.Strict as HM
-import Control.Lens
-
-type FlagName = String
-type FlagMap  = HM.HashMap FlagName Bool
-
-
--- | The conditional variables that are used to resolve the conditionals inside of
---   the cabal file. Holds the enable state of the cabal flags and the used OS and ARCH.
-data CondVars = CondVars
-   { flags :: FlagMap  -- ^ initialized with the default flag values which are accordingly
-                       --   modified by the explicitely given flag values by the user
-   , os    :: OS       -- ^ the used OS, by default the one cabal was build on or given explicitely by the user
-   , arch  :: Arch     -- ^ the used ARCH, by default the one cabal was build on or given explicitely by the user
-   } deriving (Show)
-
-
-makeLensesFor [ ("flags", "flagsL")
-              ] ''CondVars
-
-
--- | Create a 'CondVars' from the default flags of the cabal package description.
---   The 'os' and 'arch' fields are initialized by the ones the cabal library was build on.
-fromDefaults :: PD.GenericPackageDescription -> CondVars
-fromDefaults pkgDescrp = CondVars { flags = flags, os = S.buildOS, arch = S.buildArch }
-   where
-      flags = HM.fromList $ map nameWithDflt (PD.genPackageFlags pkgDescrp)
-
-      nameWithDflt PD.MkFlag { PD.flagName = PD.FlagName name, PD.flagDefault = dflt } =
-         (name, dflt)
-
-
--- | Enable the given flag in 'CondVars'.
-enableFlag :: FlagName -> CondVars -> CondVars
-enableFlag flag condVars =
-   condVars & flagsL %~ (HM.insert flag True)
-
-
--- | Disable the given flag in 'CondVars'.
-disableFlag :: FlagName -> CondVars -> CondVars
-disableFlag flag condVars =
-   condVars & flagsL %~ (HM.insert flag False)
-
-
--- | Evaluate the 'Condition' using the 'CondVars'.
-eval :: CondVars -> (Condition PD.ConfVar) -> Bool
-eval condVars cond = eval' cond
-   where
-      eval' (Var var)    = hasVar var
-      eval' (Lit val)    = val
-      eval' (CNot c)     = not $ eval' c
-      eval' (COr c1 c2)  = eval' c1 || eval' c2
-      eval' (CAnd c1 c2) = eval' c1 && eval' c2
-
-      hasVar (PD.OS osVar)                = osVar == os condVars
-      hasVar (PD.Arch archVar)            = archVar == arch condVars
-      hasVar (PD.Impl _ _ )               = True
-      hasVar (PD.Flag (PD.FlagName name))
-         | Just v <- HM.lookup name (flags condVars)
-         = v
-
-         | otherwise
-         = False
diff --git a/lib/CabalCargs/Sections.hs b/lib/CabalCargs/Sections.hs
deleted file mode 100644
--- a/lib/CabalCargs/Sections.hs
+++ /dev/null
@@ -1,19 +0,0 @@
-
-module CabalCargs.Sections
-   ( Sections(..)
-   , Section(..)
-   ) where
-
-
--- | A section of the cabal file.
-data Section = Library
-             | Executable String
-             | TestSuite String
-             | Benchmark String
-             deriving (Show, Eq)
-
-
--- | From which sections the compiler args should be collected.
-data Sections = AllSections        -- ^ all sections are considered
-              | Sections [Section] -- ^ only these sections are considered
-              deriving (Show, Eq)
diff --git a/lib/CabalCargs/Spec.hs b/lib/CabalCargs/Spec.hs
--- a/lib/CabalCargs/Spec.hs
+++ b/lib/CabalCargs/Spec.hs
@@ -6,20 +6,18 @@
    ) where
 
 import Distribution.PackageDescription (GenericPackageDescription)
-import qualified Distribution.PackageDescription as PD
 import Distribution.PackageDescription.Parse (parsePackageDescription, ParseResult(..))
 import qualified Distribution.System as Sys
 import CabalCargs.Args (Args)
-import qualified CabalCargs.BuildInfo as B
 import qualified CabalCargs.Args as A
-import qualified CabalCargs.Sections as S
 import qualified CabalCargs.Fields as F
-import qualified CabalCargs.CondVars as CV
+import qualified CabalLenses as CL
 import qualified System.IO.Strict as Strict
 import Control.Monad.Trans.Either (EitherT, left, right, runEitherT)
 import Control.Monad.IO.Class
 import Control.Monad (filterM)
 import Control.Applicative ((<$>))
+import Control.Lens
 import System.Directory (getCurrentDirectory)
 import qualified Filesystem.Path.CurrentOS as FP
 import Filesystem.Path.CurrentOS ((</>))
@@ -32,10 +30,10 @@
 
 -- | Specifies which compiler args from which sections should be collected.
 data Spec = Spec 
-   { sections      :: S.Sections                -- ^ the sections used for collecting the compiler args
+   { sections      :: [CL.Section]              -- ^ the sections used for collecting the compiler args
    , fields        :: F.Fields                  -- ^ for these fields compiler args are collected
-   , condVars      :: CV.CondVars               -- ^ used for the evaluation of the conditional fields in the cabal file
-   , cabalPackage  :: GenericPackageDescription -- ^ the package description of the read in cabal file
+   , condVars      :: CL.CondVars               -- ^ used for the evaluation of the conditional fields in the cabal file
+   , pkgDescrp     :: GenericPackageDescription -- ^ the package description of the read in cabal file
    , cabalFile     :: FilePath                  -- ^ the cabal file read from
    , distDir       :: Maybe FilePath            -- ^ the dist directory of the cabal build, a relative path to the directory of the cabal file
    , packageDB     :: Maybe FilePath            -- ^ the directory of package database of the cabal sandbox, a relative path to the directory of the cabal file
@@ -60,30 +58,26 @@
    | Just cabalFile <- A.cabalFile args = runEitherT $ do
       spec        <- fromCabalFile cabalFile
       srcSections <- io $ case A.sourceFile args of
-                               Just srcFile -> findSections srcFile cabalFile (cabalPackage spec)
+                               Just srcFile -> findSections srcFile cabalFile (pkgDescrp spec)
                                _            -> return []
 
-      right $ applyCondVars $ spec { sections      = combineSections args srcSections
+      right $ applyCondVars $ spec { sections      = combineSections (args, pkgDescrp spec) srcSections
                                    , fields        = fields_ args
                                    , relativePaths = A.relative args
                                    }
 
    | Just sourceFile <- A.sourceFile args = runEitherT $ do
       spec <- fromSourceFile sourceFile
-      let srcSections = case sections spec of
-                             S.Sections ss -> ss
-                             _             -> []
-
-      right $ applyCondVars $ spec { sections      = combineSections args srcSections
+      right $ applyCondVars $ spec { sections      = combineSections (args, pkgDescrp spec) (sections spec)
                                    , fields        = fields_ args
                                    , relativePaths = A.relative args
                                    }
 
    | otherwise = runEitherT $ do
-      curDir    <- io $ getCurrentDirectory
+      curDir    <- io getCurrentDirectory
       cabalFile <- findCabalFile curDir
       spec      <- fromCabalFile cabalFile
-      right $ applyCondVars $ spec { sections      = sections_ args
+      right $ applyCondVars $ spec { sections      = sections_ args (pkgDescrp spec)
                                    , fields        = fields_ args
                                    , relativePaths = A.relative args
                                    }
@@ -102,12 +96,12 @@
    pkgDescrp <- packageDescription file
    pkgDB     <- findPackageDB file
    distDir   <- io $ findDistDir file
-   absFile   <- FP.encodeString <$> (io $ absoluteFile file)
+   absFile   <- FP.encodeString <$> io (absoluteFile file)
    right $ Spec
-      { sections      = S.AllSections
+      { sections      = CL.allSections pkgDescrp
       , fields        = F.allFields
-      , condVars      = CV.fromDefaults pkgDescrp
-      , cabalPackage  = pkgDescrp
+      , condVars      = CL.fromDefaults pkgDescrp
+      , pkgDescrp     = pkgDescrp
       , cabalFile     = absFile
       , distDir       = distDir
       , packageDB     = pkgDB
@@ -133,10 +127,10 @@
    pkgDescrp   <- packageDescription cabalFile
    srcSections <- io $ findSections file cabalFile pkgDescrp
    right $ Spec
-      { sections      = S.Sections srcSections
+      { sections      = srcSections
       , fields        = F.allFields
-      , condVars      = CV.fromDefaults pkgDescrp
-      , cabalPackage  = pkgDescrp
+      , condVars      = CL.fromDefaults pkgDescrp
+      , pkgDescrp     = pkgDescrp
       , cabalFile     = cabalFile
       , distDir       = distDir
       , packageDB     = pkgDB
@@ -148,8 +142,8 @@
 applyFlags args spec =
    spec { condVars = disableFlags . enableFlags $ condVars spec }
    where
-      disableFlags condVars = foldr CV.disableFlag condVars (A.disable args)
-      enableFlags  condVars = foldr CV.enableFlag condVars (A.enable args)
+      disableFlags condVars = foldr CL.disableFlag condVars (A.disable args)
+      enableFlags  condVars = foldr CL.enableFlag condVars (A.enable args)
 
 
 applyOS :: Args -> Spec -> Spec
@@ -165,7 +159,7 @@
    = spec
 
    where
-      setOS name = spec { condVars = (condVars spec) { CV.os = name } }
+      setOS name = spec { condVars = (condVars spec) { CL.os = name } }
 
 
 applyArch :: Args -> Spec -> Spec
@@ -181,7 +175,7 @@
    = spec
 
    where
-      setArch name = spec { condVars = (condVars spec) { CV.arch = name } }
+      setArch name = spec { condVars = (condVars spec) { CL.arch = name } }
 
 
 packageDescription :: FilePath -> EitherT Error IO GenericPackageDescription
@@ -196,7 +190,7 @@
 --   This is done by checking if the source file is contained in the directory
 --   or a sub directory of the directories listed in the 'hs-source-dirs' field
 --   of the section.
-findSections :: FilePath -> FilePath -> GenericPackageDescription -> IO [S.Section]
+findSections :: FilePath -> FilePath -> GenericPackageDescription -> IO [CL.Section]
 findSections srcFile cabalFile pkgDescrp = do
    absSrcFile <- absoluteFile srcFile
    cabalDir   <- absoluteDirectory cabalFile
@@ -213,27 +207,17 @@
 
 type HsSourceDirs = [FP.FilePath]
 -- | Returns the hs-source-dirs of all sections present in the given package description.
-allHsSourceDirs :: GenericPackageDescription -> [(S.Section, HsSourceDirs)]
-allHsSourceDirs pkgDescrp = map fromBuildInfo buildInfos
+allHsSourceDirs :: GenericPackageDescription -> [(CL.Section, HsSourceDirs)]
+allHsSourceDirs pkgDescrp = zip sections hsSourceDirs
    where
-      fromBuildInfo (section, buildInfos) =
-         (section, toFPs $ concat $ (map (PD.hsSourceDirs . B.buildInfo)) (buildInfos condVars pkgDescrp))
+      sections     = CL.allSections pkgDescrp
+      hsSourceDirs = map (\section -> toFPs $ pkgDescrp ^. CL.buildInfoIf condVars section . CL.hsSourceDirsL) sections
+         where
+            toFPs    = map FP.decodeString
+            condVars = CL.fromDefaults pkgDescrp
 
-      buildInfos = concat [ [ (S.Library, B.buildInfosOfLib) | isJust $ PD.condLibrary pkgDescrp ]
-                          , map fromExe (PD.condExecutables pkgDescrp)
-                          , map fromTest (PD.condTestSuites pkgDescrp)
-                          , map fromBenchm (PD.condBenchmarks pkgDescrp)
-                          ]
 
-      fromExe (name, _)    = (S.Executable name, B.buildInfosOfExe name)
-      fromTest (name, _)   = (S.TestSuite name, B.buildInfosOfTest name)
-      fromBenchm (name, _) = (S.Benchmark name, B.buildInfosOfBenchmark name)
 
-      toFPs = map FP.decodeString
-
-      condVars = CV.fromDefaults pkgDescrp
-
-
 -- | Find a cabal file starting at the given directory, going upwards the directory
 --   tree until a cabal file could be found. The returned file path is absolute.
 findCabalFile :: FilePath -> EitherT Error IO FilePath
@@ -339,17 +323,17 @@
    = FP.encodeString file
 
 
-combineSections :: Args -> [S.Section] -> S.Sections
-combineSections args sections
+combineSections :: (Args, GenericPackageDescription) -> [CL.Section] -> [CL.Section]
+combineSections (args, pkgDescrp) sections
    | A.allSections args
-   = S.AllSections
+   = CL.allSections pkgDescrp
 
    | [] <- explicitSections args
    , null sections
-   = S.AllSections
+   = CL.allSections pkgDescrp
 
    | otherwise
-   = S.Sections $ explicitSections args ++ sections
+   = L.nub $ explicitSections args ++ sections
 
 
 -- | Convert the command line arguments into 'Fields'.
@@ -366,22 +350,22 @@
 
 
 -- | Convert the command line arguments into 'Sections'.
-sections_ :: Args -> S.Sections
-sections_ args
+sections_ :: Args -> GenericPackageDescription -> [CL.Section]
+sections_ args pkgDescrp
    | A.allSections args
-   = S.AllSections
+   = CL.allSections pkgDescrp
 
    | ss@(_:_) <- explicitSections args
-   = S.Sections ss
+   = ss
 
    | otherwise
-   = S.AllSections
+   = CL.allSections pkgDescrp
 
 
-explicitSections :: Args -> [S.Section]
+explicitSections :: Args -> [CL.Section]
 explicitSections args =
-   concat [ [S.Library | A.library args]
-          , map S.Executable (A.executable args)
-          , map S.TestSuite (A.testSuite args)
-          , map S.Benchmark (A.benchmark args)
+   concat [ [CL.Library | A.library args]
+          , map CL.Executable (A.executable args)
+          , map CL.TestSuite (A.testSuite args)
+          , map CL.Benchmark (A.benchmark args)
           ]
diff --git a/tests/inputFiles/withSandbox/test.cabal b/tests/inputFiles/withSandbox/test.cabal
--- a/tests/inputFiles/withSandbox/test.cabal
+++ b/tests/inputFiles/withSandbox/test.cabal
@@ -37,7 +37,8 @@
         cpp-options: -DLIB
     hs-source-dirs: lib
     other-modules: Paths_cabal_cargs
-    ghc-options: -W
+    if !impl(XXX > 20)
+        ghc-options: -W
  
 executable cabal-cargs
     build-depends: base >=3 && <5, cabal-cargs -any
diff --git a/tests/inputFiles/withoutSandbox/test.cabal b/tests/inputFiles/withoutSandbox/test.cabal
--- a/tests/inputFiles/withoutSandbox/test.cabal
+++ b/tests/inputFiles/withoutSandbox/test.cabal
@@ -37,7 +37,8 @@
         cpp-options: -DLIB
     hs-source-dirs: lib
     other-modules: Paths_cabal_cargs
-    ghc-options: -W
+    if !impl(XXX > 20)
+        ghc-options: -W
  
 executable cabal-cargs
     build-depends: base >=3 && <5, cabal-cargs -any
