diff --git a/Kit/AbsolutePath.hs b/Kit/AbsolutePath.hs
new file mode 100644
--- /dev/null
+++ b/Kit/AbsolutePath.hs
@@ -0,0 +1,15 @@
+module Kit.AbsolutePath (
+    AbsolutePath,
+    filePath,
+    absolutePath
+    ) where
+
+import System.Directory (canonicalizePath)
+
+data AbsolutePath = AbsolutePath FilePath deriving (Eq, Show)
+
+filePath :: AbsolutePath -> FilePath
+filePath (AbsolutePath fp) = fp
+
+absolutePath :: FilePath -> IO AbsolutePath
+absolutePath path = fmap AbsolutePath $ canonicalizePath path
diff --git a/Kit/Commands.hs b/Kit/Commands.hs
--- a/Kit/Commands.hs
+++ b/Kit/Commands.hs
@@ -1,29 +1,25 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving, PackageImports #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 module Kit.Commands (
   Command(),
   liftKit,
   mySpec,
   myWorkingCopy,
   myRepository,
-  runCommand,
-  defaultLocalRepository
+  runCommand
 ) where
 
 import Kit.Util
 import Kit.Spec
 import Kit.Repository
 import Kit.WorkingCopy
-
-import System.Exit (exitFailure)
-
-import "mtl" Control.Monad.Error
-import "mtl" Control.Monad.Reader
+import Control.Monad.Reader
+import Control.Error
 
 newtype Command a = Command { 
-  unCommand :: (ReaderT (WorkingCopy, KitRepository) (ErrorT String IO) a) 
+  unCommand :: ReaderT (WorkingCopy, KitRepository) Script a 
 } deriving (Monad, MonadIO, Functor, Applicative)
 
-liftKit :: KitIO a -> Command a
+liftKit :: Script a -> Command a
 liftKit = Command . ReaderT . const
 
 mySpec :: Command KitSpec
@@ -35,13 +31,11 @@
 myRepository :: Command KitRepository
 myRepository = Command $ fmap snd ask
 
-runCommand :: Maybe FilePath -> Command a -> IO ()
-runCommand repository (Command cmd) = run $ do
+runCommand :: Maybe FilePath -> Command a -> IO a
+runCommand repository (Command cmd) = runScript $ do
   spec <- currentWorkingCopy
-  repository <- liftIO $ maybe defaultLocalRepository makeRepository repository
-  runReaderT cmd (spec, repository)
-  where run = (handleFails =<<) . runErrorT
-        handleFails = either (\msg -> putStrLn ("kit error: " ++ msg) >> exitFailure) (const $ return ())
+  rep <- liftIO $ maybe defaultLocalRepository makeRepository repository
+  runReaderT cmd (spec, rep)
 
 defaultLocalRepository :: IO KitRepository
 defaultLocalRepository = makeRepository =<< (</> ".kit" ) <$> getHomeDirectory
diff --git a/Kit/Contents.hs b/Kit/Contents.hs
--- a/Kit/Contents.hs
+++ b/Kit/Contents.hs
@@ -7,17 +7,16 @@
 import Kit.Spec
 import Kit.Util
 import Kit.Xcode.XCConfig
-import Kit.FilePath
-
-import qualified Data.Traversable as T
+import Kit.AbsolutePath
+import Kit.FlaggedFile
 
 -- | The determined contents of a particular Kit
 data KitContents = KitContents { 
   contentSpec :: KitSpec, -- ^ The dependency the contents were created from
   contentBaseDir :: FilePath, -- ^ Path to where the content was loaded from
-  contentHeaders :: [FilePath],     -- ^ Paths to headers
-  contentSources :: [FilePath],     -- ^ Paths to source files
-  contentLibs :: [FilePath],        -- ^ Paths to static libs
+  contentHeaders :: [FlaggedFile],     -- ^ Paths to headers
+  contentSources :: [FlaggedFile],     -- ^ Paths to source files
+  contentLibs :: [FlaggedFile],        -- ^ Paths to static libs
   contentConfig :: Maybe XCConfig,  -- ^ Contents of the xcconfig base file
   contentPrefix :: Maybe String,     -- ^ Contents of the prefix header
   contentResourceDir :: Maybe FilePath
@@ -33,9 +32,10 @@
 readKitContents :: (Applicative m, MonadIO m) => AbsolutePath -> KitSpec -> m KitContents
 readKitContents absKitDir spec =
   let kitDir = filePath absKitDir 
-      find dir tpe = liftIO $ inDirectory kitDir $ do
-        files <- glob (dir </> "**/*" ++ tpe)
-        mapM canonicalizePath files
+      -- We need to flag every file with objc-arc or not, if we do it
+      -- project wide things get really messy.
+      flags = if specWithARC spec then "-fobjc-arc" else "-fno-objc-arc"
+      find dir tpe = fmap (flaggedFile flags) <$> findFiles kitDir dir tpe
       findSrc = find $ specSourceDirectory spec
       headers = findSrc ".h"
       sources = findSrc .=<<. [".m", ".mm", ".c"]
@@ -48,20 +48,15 @@
         if b 
           then Just <$> canonicalizePath r
           else return Nothing
-  in  KitContents spec kitDir <$> headers <*> sources <*> libs <*> config <*> prefix <*> resourceDir
+   in KitContents spec kitDir <$> headers <*> sources <*> libs <*> config <*> prefix <*> resourceDir
 
 -- TODO report missing file
 readHeader :: FilePath -> KitSpec -> IO (Maybe String)
-readHeader kitDir spec = do
-  let fp = kitDir </> specPrefixFile spec
-  exists <- doesFileExist fp
-  T.sequence (fmap readFile $ ifTrue exists fp)
+readHeader kitDir spec = readFile' $ kitDir </> specPrefixFile spec
 
 -- TODO report missing file
 readConfig :: FilePath -> KitSpec -> IO (Maybe XCConfig)
 readConfig kitDir spec = do
-  let fp = kitDir </> specConfigFile spec
-  exists <- doesFileExist fp
-  contents <- T.sequence (fmap readFile $ ifTrue exists fp)
+  contents <- readFile' $ kitDir </> specConfigFile spec
   return $ fmap (fileContentsToXCC $ packageName spec) contents
 
diff --git a/Kit/Dependency.hs b/Kit/Dependency.hs
--- a/Kit/Dependency.hs
+++ b/Kit/Dependency.hs
@@ -5,19 +5,18 @@
     dependency,
     depSpec,
     isDevDep,
-    dependencyTree,
-    devKitDir -- TODO, cleanup main, might not need to export
+    dependencyTree
   ) where
 
+import Control.Error
 import Kit.Util
 import Kit.Spec
 import Kit.Repository
 import Kit.WorkingCopy
 import Data.Tree (Tree, levels, unfoldTreeM)
 import Data.List (nub)
-import Data.Maybe (isJust)
 
-data Dependency = Dependency { depSpec :: KitSpec, mbKitPath :: (Maybe FilePath) } deriving (Eq, Show)
+data Dependency = Dependency { depSpec :: KitSpec, mbKitPath :: Maybe FilePath } deriving (Eq, Show)
 
 -- Fold over a dependency
 dependency :: (KitSpec -> a) -> (FilePath -> KitSpec -> a) -> Dependency -> a
@@ -31,30 +30,32 @@
 isDevDep :: Dependency -> Bool
 isDevDep = isJust . mbKitPath
 
+-- todo: check for version ranges :)
+totalSpecDependencies :: KitRepository -> WorkingCopy -> Script [Dependency]
+totalSpecDependencies repo workingCopy = refineDeps <$> dependencyTree repo workingCopy
+
 -- | Return all the (unique) children of this tree (except the top node), in reverse depth order.
 refineDeps :: Eq a => Tree a -> [a]
 refineDeps = nub . concat . reverse . drop 1 . levels
 
--- todo: check for version ranges :)
-totalSpecDependencies :: KitRepository -> WorkingCopy -> KitIO [Dependency]
-totalSpecDependencies repo workingCopy = refineDeps <$> dependencyTree repo workingCopy
-
-dependencyTree :: KitRepository -> WorkingCopy -> KitIO (Tree Dependency)
+dependencyTree :: KitRepository -> WorkingCopy -> Script (Tree Dependency)
 dependencyTree repo workingCopy = unfoldTreeM (unfoldDeps repo devPackages) baseSpec
   where devPackages = workingDevPackages workingCopy
         baseSpec = workingKitSpec workingCopy
 
+unfoldDeps :: KitRepository -> DevPackages -> KitSpec -> Script (Dependency, [KitSpec])
+unfoldDeps kr devPackages = unfolder (mapM (lookupX kr devPackages) . specDependencies . depSpec) . lookupDependency devPackages 
+
 lookupDependency :: DevPackages -> KitSpec -> Dependency
-lookupDependency devPackages ks = maybe (Dependency ks Nothing) (\(ks',fp) -> Dependency ks' (Just fp)) thisDev
-    where thisDev = findDevPackage devPackages ks
+lookupDependency devPackages ks = maybe (Dependency ks Nothing) (\(devSpec,fp) -> Dependency devSpec (Just fp)) thisDev
+      where thisDev = findDevPackage devPackages ks
 
-findKitSpec :: DevPackages -> Kit -> Maybe KitSpec
-findKitSpec devPackages kit = fmap fst $ findDevPackage devPackages kit
+unfolder :: Functor m => (a -> m b) -> a -> m (a, b)
+unfolder f b = (b,) <$> f b
 
-unfoldDeps :: KitRepository -> DevPackages -> KitSpec -> KitIO (Dependency, [KitSpec])
-unfoldDeps kr devPackages spec = let rootDep = lookupDependency devPackages spec
-                                     lookup' kit = maybe (readKitSpec kr kit) return $ findKitSpec devPackages kit 
-                                  in do
-                                      children <- mapM lookup' . specDependencies . depSpec $ rootDep
-                                      return (rootDep, children)
+lookupX :: MonadIO m => KitRepository -> DevPackages -> Kit -> EitherT String m KitSpec
+lookupX kr devPackages kit = maybe (readKitSpec kr kit) return $ findDevKitSpec devPackages kit 
+
+findDevKitSpec :: DevPackages -> Kit -> Maybe KitSpec
+findDevKitSpec devPackages kit = fmap fst $ findDevPackage devPackages kit
 
diff --git a/Kit/FilePath.hs b/Kit/FilePath.hs
deleted file mode 100644
--- a/Kit/FilePath.hs
+++ /dev/null
@@ -1,15 +0,0 @@
-module Kit.FilePath (
-    AbsolutePath,
-    filePath,
-    absolutePath
-    ) where
-
-import System.Directory (canonicalizePath)
-
-data AbsolutePath = AbsolutePath FilePath deriving (Eq, Show)
-
-filePath :: AbsolutePath -> FilePath
-filePath (AbsolutePath fp) = fp
-
-absolutePath :: FilePath -> IO AbsolutePath
-absolutePath path = fmap AbsolutePath $ canonicalizePath path
diff --git a/Kit/Main.hs b/Kit/Main.hs
--- a/Kit/Main.hs
+++ b/Kit/Main.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE PackageImports #-}
 module Kit.Main where
 
   import qualified Kit.CmdArgs as KA 
@@ -10,6 +9,7 @@
   import Kit.Contents
   import Kit.Dependency
   import Kit.WorkingCopy
+  import Data.Yaml (encodeFile)
   import Kit.Util.FSAction
   import System.Exit
   import Data.Tree (drawTree)
@@ -17,15 +17,12 @@
   import Data.Function (on)
   import Kit.Repository (KitRepository, unpackKit, packagesDirectory, publishLocally)
   import Control.Monad.State
-  import Kit.FilePath
+  import Kit.AbsolutePath
 
   kitMain :: IO ()
   kitMain = do
     args <- KA.parseArgs
-    let action = runCommand (KA.repositoryDir args) . handleArgs $ args
-    catch action $ \e -> do
-        sayError $ show e
-        exitWith $ ExitFailure 1 
+    runCommand (KA.repositoryDir args) . handleArgs $ args
 
   handleArgs :: KA.KitCmdArgs -> Command ()
   handleArgs (KA.Update _) = doUpdate
@@ -43,7 +40,7 @@
                 rawDeps <- totalSpecDependencies repo workingCopy
                 (deps, didResolveConflict) <- unconflict rawDeps
                 let (devPackages, repoPackages) = partition isDevDep deps
-                mapM_ (unpackKit repo) repoPackages
+                mapM_ (liftIO . unpackKit repo) repoPackages
                 mapM_ (sayError . ("Using dev-package: " ++) . packageName) devPackages
                 project <- buildProject repo workingCopy deps
                 reportResources project
@@ -58,14 +55,14 @@
             writeProject = liftIO . runActions . kitProjectActions
 
   unconflict :: (Packageable b, MonadIO m) => [b] -> m ([b], Bool)
-  unconflict deps = let byName = groupBy ((==) `on` (packageName . snd)) . sortBy (compare `on` (packageName . snd)) $ zip [1..] deps
+  unconflict deps = let byName = groupBy ((==) `on` (packageName . snd)) . sortBy (compare `on` (packageName . snd)) $ zip [(1::Int)..] deps
                         stripIndex (xs, hadConflict) = (map snd . sortBy (compare `on` fst) $ xs, hadConflict)
-                in liftM stripIndex $ flip runStateT False $ forM byName $ \all@(b:bs) ->
+                in liftM stripIndex $ flip runStateT False $ forM byName $ \allDeps@(b:bs) ->
                     if null bs
                       then return b
                       else do
-                        let versions = nub $ map (packageVersion . snd) all
-                        let maxVersion = maximumBy (compare `on` (packageVersion . snd)) all
+                        let versions = nub $ map (packageVersion . snd) allDeps
+                        let maxVersion = maximumBy (compare `on` (packageVersion . snd)) allDeps
                         sayWarn $ "Dependency conflict: " ++ packageName (snd b) ++ " => " ++ intercalate ", " versions
                         sayWarn $ "Selected maximum version: " ++ (packageVersion . snd $ maxVersion)
                         put True
@@ -73,7 +70,7 @@
 
   dependencyContents :: (Applicative m, MonadIO m) => KitRepository -> Dependency -> m KitContents
   dependencyContents repo dep = readKitContents' baseDir (depSpec dep) where
-    baseDir = dependency ((packagesDirectory repo </>) . packageFileName) (\fp spec -> devKitDir </> fp) dep
+    baseDir = dependency ((packagesDirectory repo </>) . packageFileName) (\fp _ -> devKitDir </> fp) dep
     readKitContents' base spec = do
       absoluteBase <- liftIO $ absolutePath base
       readKitContents absoluteBase spec
@@ -106,11 +103,11 @@
         puts " #> Deploying locally"
         doPublishLocal Nothing -- TODO publish with a verify tag
         puts " #> Building temporary parent project"
-        liftIO $ inDirectory getTemporaryDirectory $ do
+        liftIO $ inDirectoryM getTemporaryDirectory $ do
           let kitVerifyDir = "kit-verify"
           cleanOrCreate kitVerifyDir
           inDirectory kitVerifyDir $ do
-            writeSpec "KitSpec" (defaultSpec "verify-kit" "1.0") { specDependencies = [specKit spec] }
+            encodeFile "KitSpec" (defaultSpec "verify-kit" "1.0") { specDependencies = [specKit spec] }
             runCommand Nothing doUpdate 
             inDirectory "Kits" $ do
               shell "open ."
@@ -121,6 +118,6 @@
   doCreateSpec :: String -> String -> Command ()
   doCreateSpec name version = do
     let spec = defaultSpec name version 
-    writeSpec "KitSpec" spec
+    liftIO $ encodeFile "KitSpec" spec
     puts $ "Created KitSpec for " ++ packageFileName spec
 
diff --git a/Kit/Package.hs b/Kit/Package.hs
--- a/Kit/Package.hs
+++ b/Kit/Package.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE PackageImports #-}
 module Kit.Package (package) where
   import Kit.Spec
   import Kit.Util
@@ -6,14 +5,15 @@
 
   fileBelongsInPackage :: KitSpec -> FilePath -> Bool
   fileBelongsInPackage config fp = isCore || isProject where
-    isCore = elem fp [specResourcesDirectory config, specSourceDirectory config, specTestDirectory config, specLibDirectory config, "KitSpec"]
+    isCore = fp `elem` [specResourcesDirectory config, specSourceDirectory config, specTestDirectory config, specLibDirectory config, "KitSpec"]
     isProject = any (`isSuffixOf` fp) ["xcodeproj", "xcconfig", ".pch"] -- TODO this could just check for the defined config and prefi header
 
   package :: KitSpec -> IO ()
   package spec = do
       contents <- filter (fileBelongsInPackage spec) <$> getDirectoryContents "."
       mkdirP distDir
-      sh $ envDontCopy ++ " tar -czf " ++ (distDir </> (kitPath ++ ".tar.gz")) ++ " -s ,^," ++ kitPath ++ "/, " ++ join (intersperse " " contents)
+      let escapedContents = map (\x -> "\"" ++ x ++ "\"") contents
+      sh $ envDontCopy ++ " tar -czf " ++ (distDir </> (kitPath ++ ".tar.gz")) ++ " -s ,^," ++ kitPath ++ "/, " ++ join (intersperse " " escapedContents)
       return ()
     where
       distDir = "dist"
diff --git a/Kit/Project.hs b/Kit/Project.hs
--- a/Kit/Project.hs
+++ b/Kit/Project.hs
@@ -12,8 +12,6 @@
 import Kit.Util.FSAction
 import Kit.Xcode.Builder
 import Kit.Xcode.XCConfig
-import Data.List
-import Data.Function
 import Data.Maybe
 import qualified Data.Map as M
 
@@ -74,8 +72,8 @@
       resources = mapMaybe resourceLink kitsContents
    in KitProject pf header config depsConfig resources
   where createProjectFile cs = let
-                 headers = sortBy (compare `on` takeFileName) (concatMap contentHeaders cs)
-                 sources = sortBy (compare `on` takeFileName) (concatMap contentSources cs)
+                 headers = concatMap contentHeaders cs
+                 sources = concatMap contentSources cs
                  libs = concatMap contentLibs cs
               in renderXcodeProject headers sources libs "libKitDeps.a"
         createHeader cs = let
diff --git a/Kit/Repository.hs b/Kit/Repository.hs
--- a/Kit/Repository.hs
+++ b/Kit/Repository.hs
@@ -1,11 +1,8 @@
-{-# LANGUAGE PackageImports #-}
 module Kit.Repository (
     --
     KitRepository,
     makeRepository,
     --
-    copyKitPackage,
-    explodePackage,
     readKitSpec,
     unpackKit,
     packagesDirectory,
@@ -14,9 +11,8 @@
 
   import Kit.Spec
   import Kit.Util
-
-  import qualified Data.Traversable as T
-  import qualified Data.ByteString as BS
+  import Data.Yaml (decodeFile)
+  import Control.Error
 
   data KitRepository = KitRepository { dotKitDir :: FilePath } deriving (Eq, Show)
 
@@ -28,27 +24,10 @@
     mkdirP $ localCacheDir repo
     return repo
 
-  explodePackage :: KitRepository -> Kit -> IO ()
-  explodePackage kr kit = do
-    let packagesDir = localCacheDir kr
-    let packagePath = localCacheDir kr </> kitPackagePath kit
-    mkdirP packagesDir
-    inDirectory packagesDir $ shell ("tar zxvf " ++ packagePath)
-    return ()
-
-  copyKitPackage :: KitRepository -> Kit -> FilePath -> IO ()
-  copyKitPackage repo kit = copyFile (localCacheDir repo </> kitPackagePath kit)
-
-  readKitSpec :: KitRepository -> Kit -> KitIO KitSpec
+  readKitSpec :: MonadIO m => KitRepository -> Kit -> EitherT String m KitSpec
   readKitSpec repo kit = do
-    mbKitStuff <- liftIO $ readIfExists (localCacheDir repo </> kitSpecPath kit)
-    contents <- maybeToKitIO ("Missing " ++ packageFileName kit) mbKitStuff
-    maybeToKitIO ("Invalid KitSpec file for " ++ packageFileName kit) $ decodeSpec contents
-
-  readIfExists :: String -> IO (Maybe BS.ByteString)
-  readIfExists file = do
-    exists <- doesFileExist file
-    T.sequenceA $ ifTrue exists $ BS.readFile file
+    mbLoaded <- liftIO $ decodeFile (localCacheDir repo </> kitSpecPath kit)
+    tryJust ("Invalid KitSpec file for " ++ packageFileName kit) mbLoaded
 
   baseKitPath :: Packageable a => a -> String
   baseKitPath k = packageName k </> packageVersion k
@@ -62,29 +41,29 @@
   packagesDirectory :: KitRepository -> FilePath
   packagesDirectory kr = dotKitDir kr </> "packages"
 
-  unpackKit :: (Packageable a, MonadIO m) => KitRepository -> a -> m ()
+  unpackKit :: (Packageable a) => KitRepository -> a -> IO ()
   unpackKit kr kit = do
-      let source = (localCacheDir kr </> kitPackagePath kit)
+      let source = localCacheDir kr </> kitPackagePath kit
       let dest = packagesDirectory kr
-      d <- liftIO $ doesDirectoryExist $ dest </> packageFileName kit
+      d <- doesDirectoryExist $ dest </> packageFileName kit
       if not d 
         then do
-          puts $ "Unpacking: " ++ packageFileName kit
+          putStrLn $ "Unpacking: " ++ packageFileName kit
           mkdirP dest 
-          liftIO $ inDirectory dest $ shell ("tar zxf " ++ source)
+          inDirectory dest $ shell ("tar zxf " ++ source)
           return ()
-        else puts $ "Using: " ++ packageFileName kit
+        else putStrLn $ "Using: " ++ packageFileName kit
       return ()
 
   publishLocally :: KitRepository -> KitSpec -> FilePath -> FilePath -> IO ()
   publishLocally kr ks specFile packageFile = do
                               let cacheDir = localCacheDir kr
-                              let thisKitDir = cacheDir </> baseKitPath (specKit ks)
+                              let thisKitDir = cacheDir </> baseKitPath ks
                               mkdirP thisKitDir
                               let fname = takeFileName packageFile
                               copyFile packageFile (thisKitDir </> fname)
                               copyFile specFile (thisKitDir </> "KitSpec")
-                              let pkg = packagesDirectory kr </> packageFileName (specKit ks)
+                              let pkg = packagesDirectory kr </> packageFileName ks
                               d <- doesDirectoryExist pkg
                               when d $ removeDirectoryRecursive pkg
 
diff --git a/Kit/Spec.hs b/Kit/Spec.hs
--- a/Kit/Spec.hs
+++ b/Kit/Spec.hs
@@ -8,19 +8,13 @@
   Packageable(..),
   packageFileName,
   -- | Utils
-  defaultSpec,
-  -- | Serialisation
-  decodeSpec,
-  encodeSpec,
-  writeSpec
+  defaultSpec
   ) where
 
   import Kit.Util
- 
   import Data.Yaml
   import Data.HashMap.Strict as HM (toList) 
   import Data.Text as T (unpack, pack)
-  import qualified Data.ByteString as BS 
   import Data.Maybe (maybeToList)
   import Data.Attoparsec.Number
 
@@ -33,6 +27,7 @@
     specResourcesDirectory :: FilePath,
     specPrefixFile :: FilePath,
     specConfigFile :: FilePath,
+    specWithARC :: Bool,
     specKitDepsXcodeFlags :: Maybe String
   } deriving (Show, Read, Eq)
 
@@ -60,26 +55,17 @@
     packageVersion = kitVersion . specKit
 
   defaultSpec :: String -> String -> KitSpec
-  defaultSpec name version = KitSpec (Kit name version) [] "src" "test" "lib" "resources" "Prefix.pch" "Config.xcconfig" Nothing 
+  defaultSpec name version = KitSpec (Kit name version) [] "src" "test" "lib" "resources" "Prefix.pch" "Config.xcconfig" False Nothing 
   -- TODO make this and the json reading use the same defaults
   -- I suspect that to do this I'll need update functions for each of
   -- fields in the KitSpec record.
   -- Look at the 'data-lens' package on hackage. (or comonad-transformers)
 
-  decodeSpec :: BS.ByteString -> Maybe KitSpec
-  decodeSpec = decode
-
-  encodeSpec :: KitSpec -> BS.ByteString
-  encodeSpec = encode
-
-  writeSpec :: MonadIO m => FilePath -> KitSpec -> m ()
-  writeSpec fp spec = liftIO $ BS.writeFile fp $ encodeSpec spec
-
   instance ToJSON Kit where
     toJSON kit = object ["name" .= kitName kit, "version" .= kitVersion kit]
 
   showNum :: Number -> String
-  showNum l = show l
+  showNum = show
 
   instance FromJSON Kit where
     parseJSON (Object obj) = (Kit <$> obj .: "name" <*> (obj .: "version" <|> (showNum <$> obj .: "version"))) <|> case HM.toList obj of
@@ -93,14 +79,15 @@
     toJSON spec = object ([
          "name" .= (kitName . specKit) spec,
          "version" .= (kitVersion . specKit) spec,
-         "dependencies" .= (map makeDep (specDependencies spec)),
+         "dependencies" .= map makeDep (specDependencies spec),
          "source-directory" .= specSourceDirectory spec,
          "test-directory" .= specTestDirectory spec,
          "lib-directory" .= specLibDirectory spec,
          "resources-directory" .= specResourcesDirectory spec,
          "prefix-header" .= specPrefixFile spec,
+         "with-arc" .= specWithARC spec,
          "xcconfig" .= specConfigFile spec
-      ] ++ maybeToList (fmap (("kitdeps-xcode-flags" .=)) (specKitDepsXcodeFlags spec)))
+      ] ++ maybeToList (fmap ("kitdeps-xcode-flags" .=) (specKitDepsXcodeFlags spec)))
       where makeDep dep = object [(T.pack $ kitName dep, String . T.pack $ kitVersion dep)]
 
   instance FromJSON KitSpec where
@@ -112,5 +99,6 @@
                                     <*> (obj .:? "resources-directory" .!= "resources")
                                     <*> (obj .:? "prefix-header" .!= "Prefix.pch")
                                     <*> (obj .:? "xcconfig" .!= "Config.xcconfig")
+                                    <*> (obj .:? "with-arc" .!= False)
                                     <*> (Just <$> obj .:? "kitdeps-xcode-flags") .!= Nothing
-
+    parseJSON _ = fail "Couldn't parse KitSpec"
diff --git a/Kit/Util.hs b/Kit/Util.hs
--- a/Kit/Util.hs
+++ b/Kit/Util.hs
@@ -1,37 +1,34 @@
-{-# LANGUAGE FlexibleInstances, TypeSynonymInstances, PackageImports #-}
-
 module Kit.Util(
   module Kit.Util,
-  module Control.Applicative,
-  module Control.Monad,
-  module System.Directory,
-  module System.FilePath.Posix,
-  module Control.Monad.Trans,
+  module Exported,
   Color(..),
-  (>>>)
+  (</>), takeFileName, takeDirectory,
+  tryJust
   ) where
+  
+  import Control.Applicative as Exported
+  import Control.Monad.Trans as Exported
+  import Control.Monad as Exported
+  import System.Directory as Exported
 
-  import System.Directory
-  import System.FilePath.Posix
+  import System.FilePath.Posix ((</>), takeFileName, takeDirectory)
   import System.FilePath.Glob (globDir1, compile)
 
-  import System.Posix.Env (getEnv)
+  import System.Environment (getEnv)
 
+  import Control.Error
+
   import Data.List
-  import Data.Maybe
   import Data.Monoid
   import Data.Traversable as T
 
-  import Control.Arrow
-  import Control.Applicative
-  import Control.Monad
-  import Control.Monad.Error
-  import Control.Monad.Trans
   import System.Cmd
 
+  import Kit.AbsolutePath
+
   import System.Console.ANSI
 
-  import qualified "mtl" Control.Monad.State as S
+  import Control.Monad.State as S
 
   popS :: S.State [a] a
   popS = do
@@ -40,33 +37,17 @@
     return x
 
   shell :: String -> IO ()
-  shell c = do
-    _ <- system c
-    return ()
+  shell = void . system
 
   when' :: Monad m => m Bool -> m () -> m ()
   when' a b = a >>= flip when b
 
   puts :: MonadIO m => String -> m ()
-  puts a = liftIO $ putStrLn a
-
-  maybeRead :: Read a => String -> Maybe a
-  maybeRead = fmap fst . listToMaybe . reads
+  puts = liftIO . putStrLn
 
   ifTrue :: MonadPlus m => Bool -> a -> m a
   ifTrue p a = if p then return a else mzero
 
-  maybeToRight :: b -> Maybe a -> Either b a
-  maybeToRight v = maybe (Left v) Right
-
-  maybeToLeft :: b -> Maybe a -> Either a b
-  maybeToLeft v = maybe (Right v) Left
-
-  type KitIO a = ErrorT String IO a
-  
-  maybeToKitIO :: String -> Maybe a -> KitIO a
-  maybeToKitIO msg = maybe (throwError msg) return
-
   mkdirP :: MonadIO m => FilePath -> m ()
   mkdirP = liftIO . createDirectoryIfMissing True
 
@@ -75,21 +56,25 @@
     exists <- doesDirectoryExist directory
     when exists $ removeDirectoryRecursive directory
     mkdirP directory
-
-  -- Typeclass so that inDirectory can act on effectful values
-  class FilePathM a where filePathM :: MonadIO m => a -> m FilePath
-  instance FilePathM FilePath where filePathM = return 
-  instance FilePathM (IO FilePath) where filePathM = liftIO . id
     
-  inDirectory :: (FilePathM p, MonadIO m) => p -> m a -> m a
+  inDirectory :: MonadIO m => FilePath -> m a -> m a
   inDirectory fp actions = do
     cwd <- liftIO getCurrentDirectory
-    dir <- filePathM fp
-    liftIO $ setCurrentDirectory dir
+    liftIO $ setCurrentDirectory fp
     v <- actions
     liftIO $ setCurrentDirectory cwd
     return v
 
+  inDirectoryM :: (MonadIO m) => m FilePath -> m a -> m a
+  inDirectoryM m a = do
+    v <- m
+    inDirectory v a
+
+  findFiles :: MonadIO m => FilePath -> FilePath -> String -> m [AbsolutePath]
+  findFiles kitDir dir tpe = liftIO $ inDirectory kitDir $ do
+                                files <- glob (dir </> "**/*" ++ tpe)
+                                T.mapM absolutePath files
+
   glob :: String -> IO [String]
   glob pattern = globDir1 (compile pattern) ""
 
@@ -105,8 +90,11 @@
   (.=<<.) f =
     liftM join . T.mapM f
 
+  getEnv' :: String -> IO (Maybe String)
+  getEnv' = fmap hush . runEitherT . tryIO . getEnv
+
   isSet :: String -> IO Bool
-  isSet = fmap isJust . getEnv 
+  isSet = fmap isJust . getEnv'
     
   say :: MonadIO m => Color -> String -> m ()
   say color msg = do
@@ -124,4 +112,9 @@
 
   sayWarn :: MonadIO m => String -> m ()
   sayWarn = say Yellow
+
+  readFile' :: (MonadPlus t, T.Traversable t) => FilePath -> IO (t String)
+  readFile' fp = do
+      exists <- doesFileExist fp
+      T.sequence (fmap readFile $ ifTrue exists fp)
 
diff --git a/Kit/Util/FSAction.hs b/Kit/Util/FSAction.hs
--- a/Kit/Util/FSAction.hs
+++ b/Kit/Util/FSAction.hs
@@ -3,6 +3,8 @@
 import System.FilePath
 import System.Posix.Files
 
+import Control.Error
+
 import Kit.Util
 import Data.List (intersperse)
 
@@ -22,13 +24,13 @@
     renameFile tempPath atPath
   where tempPath = atPath ++ "_"
 runAction (Symlink target name) = do
-  catch (removeLink name) (\_ -> return ())
+  _ <- runEitherT . scriptIO $ removeLink name
   -- When a `name` has parent directories, symbolic link target needs to be made relative to that file
   -- need to consider "./name"
   let relFix = join $ intersperse "/" $ map (const "..") (init $ splitDirectories name)
   mkdirP $ dropFileName name
-  catch (when' (fileExist target) $ createSymbolicLink (relFix </> target) name) $ \e -> do
-    error $ "An error occured when creating a symlink to " ++ target ++ " called " ++ name ++ ": " ++ show e
+  let printError e = "An error occured when creating a symlink to " ++ target ++ " called " ++ name ++ ": " ++ show e
+  runScript . fmapLT printError . scriptIO $ when' (fileExist target) (createSymbolicLink (relFix </> target) name)
 
 runAction (InDir dir action) = do
   mkdirP dir
diff --git a/Kit/WorkingCopy.hs b/Kit/WorkingCopy.hs
--- a/Kit/WorkingCopy.hs
+++ b/Kit/WorkingCopy.hs
@@ -8,11 +8,10 @@
     ) where
 
 import Kit.Util
+import Data.Yaml (decodeFile)
 import Kit.Spec
 import qualified Data.List as L
-
-import "mtl" Control.Monad.Error
-import qualified Data.ByteString as BS
+import Control.Error
 
 devKitDir :: String
 devKitDir = "dev-packages"
@@ -28,7 +27,7 @@
 findDevPackage :: Packageable a => DevPackages -> a -> Maybe (KitSpec, FilePath)
 findDevPackage (DevPackages pkgs) kit = L.find ((packageName kit ==) . packageName . fst) pkgs
 
-currentWorkingCopy :: KitIO WorkingCopy
+currentWorkingCopy :: Script WorkingCopy
 currentWorkingCopy = do
   let specFile = "KitSpec"
   spec <- readSpec specFile
@@ -37,11 +36,7 @@
   devKitSpecs <- mapM f devKitSpecFiles
   return $ WorkingCopy spec specFile $ DevPackages devKitSpecs
 
-readSpec :: FilePath -> KitIO KitSpec
-readSpec path = checkExists path >>= liftIO . BS.readFile >>= ErrorT . return . parses
-  where checkExists pathToSpec = do
-          doesExist <- liftIO $ doesFileExist pathToSpec 
-          if doesExist
-            then return pathToSpec 
-            else throwError ("Couldn't find the spec at " ++ pathToSpec)
-        parses = maybeToRight "Parse error in KitSpec file" . decodeSpec
+readSpec :: FilePath -> Script KitSpec
+readSpec path = do
+    mbKitSpec <- liftIO $ decodeFile path
+    tryJust ("Error loading spec file " ++ path) mbKitSpec
diff --git a/Kit/Xcode/Builder.hs b/Kit/Xcode/Builder.hs
--- a/Kit/Xcode/Builder.hs
+++ b/Kit/Xcode/Builder.hs
@@ -2,28 +2,33 @@
 module Kit.Xcode.Builder (renderXcodeProject) where
   import Kit.Xcode.Common
   import Kit.Xcode.ProjectFileTemplate
+  import Kit.FlaggedFile
   import Text.PList
-  import qualified Text.PList.PrettyPrint as PList (pp, ppFlat)
+  import qualified Text.PList.PrettyPrint as PList (ppFlat)
   import Kit.Util
-  import Data.List (nub)
+  import Data.List (nub, sortBy)
   import "mtl" Control.Monad.State
+  import System.FilePath
+  import Data.Function (on)
 
-  createBuildFile :: Integer -> FilePath -> PBXBuildFile
-  createBuildFile i path = PBXBuildFile uuid1 $ PBXFileReference uuid2 path
+  createBuildFile :: Integer -> FlaggedFile -> PBXBuildFile
+  createBuildFile i ffpath = PBXBuildFile uuid1 (PBXFileReference uuid2 path) compileFlags
     where uuid1 = uuid i
           uuid2 = uuid $ i + 10000000
+          path = flaggedFilePath ffpath
+          compileFlags = flaggedFileFlags ffpath
 
-  buildFileFromState :: FilePath -> State [Integer] PBXBuildFile
+  buildFileFromState :: FlaggedFile -> State [Integer] PBXBuildFile
   buildFileFromState filePath = flip createBuildFile filePath <$> popS 
 
   -- | Render an Xcode project!
   renderXcodeProject :: 
-    [FilePath]    -- ^ Headers  
-    -> [FilePath] -- ^ Sources
-    -> [FilePath] -- ^ Static Libs
+    [FlaggedFile]    -- ^ Headers  
+    -> [FlaggedFile] -- ^ Sources
+    -> [FlaggedFile] -- ^ Static Libs
     -> String     -- ^ Output lib name
     -> String     
-  renderXcodeProject headers sources libs outputLibName = fst . flip runState [1..] $ do
+  renderXcodeProject headers sources libs outputLibName = fst . flip runState [(1::Integer)..] $ do
       headerBuildFiles <- mapM buildFileFromState headers
       sourceBuildFiles <- mapM buildFileFromState sources
       libBuildFiles <- mapM buildFileFromState libs -- Build File Items
@@ -32,21 +37,21 @@
           bfs = buildFileSection allBuildFiles
           frs = fileReferenceSection (map buildFileReference allBuildFiles) outputLibName 
           -- Groups
-          classes = classesGroup $ map buildFileReference (sourceBuildFiles ++ headerBuildFiles)
+          classes = classesGroup $ sortBy (compare `on` (takeFileName . fileReferencePath)) $ map buildFileReference (sourceBuildFiles ++ headerBuildFiles)
           fg = frameworksGroup $ map buildFileReference libBuildFiles
           -- Phases
           headersPhase = headersBuildPhase headerBuildFiles
           srcsPhase = sourcesBuildPhase sourceBuildFiles
           frameworksPhase = frameworksBuildPhase libBuildFiles
           -- UUID indices
-          libDirs = nub $ map dropFileName libs 
+          libDirs = nub $ map (dropFileName . flaggedFilePath) libs 
       return . PList.ppFlat $ makeProjectPList (bfs ++ frs ++ [classes, headersPhase, srcsPhase, frameworksPhase, fg]) libDirs
 
   buildFileSection :: [PBXBuildFile] -> [PListObjectItem]
   buildFileSection bfs = map buildFileItem bfs ++ [
-      "4728C530117C02B10027D7D1" ~> buildFile kitConfigRefUUID,
-      "AA747D9F0F9514B9006C5449" ~> buildFile "AA747D9E0F9514B9006C5449",
-      "AACBBE4A0F95108600F1A2B1" ~> buildFile "AACBBE490F95108600F1A2B1"
+      "4728C530117C02B10027D7D1" ~> buildFile kitConfigRefUUID "",
+      "AA747D9F0F9514B9006C5449" ~> buildFile "AA747D9E0F9514B9006C5449" "",
+      "AACBBE4A0F95108600F1A2B1" ~> buildFile "AACBBE490F95108600F1A2B1" ""
     ]
 
   fileReferenceSection :: [PBXFileReference] -> String -> [PListObjectItem]
diff --git a/Kit/Xcode/Common.hs b/Kit/Xcode/Common.hs
--- a/Kit/Xcode/Common.hs
+++ b/Kit/Xcode/Common.hs
@@ -20,7 +20,8 @@
 
 data PBXBuildFile = PBXBuildFile {
   buildFileId :: UUID,
-  buildFileReference :: PBXFileReference
+  buildFileReference :: PBXFileReference,
+  buildFileFlags :: String
 } deriving (Eq, Show)
   
 data PBXFileReference = PBXFileReference {
@@ -36,11 +37,11 @@
     "children" ~> arr children
   ]
 
-buildFile :: String -> PListType
-buildFile refUUID = obj [ "isa" ~> val "PBXBuildFile", "fileRef" ~> val refUUID ]
+buildFile :: String -> String -> PListType
+buildFile refUUID flags = obj [ "isa" ~> val "PBXBuildFile", "fileRef" ~> val refUUID, "settings" ~> obj ["COMPILER_FLAGS" ~> val flags ]]
 
 buildFileItem :: PBXBuildFile -> PListObjectItem 
-buildFileItem bf = buildFileId bf ~> buildFile (fileReferenceId . buildFileReference $ bf) 
+buildFileItem bf = buildFileId bf ~> (buildFile (fileReferenceId . buildFileReference $ bf) (buildFileFlags bf))
 
 fileReferenceItem :: PBXFileReference -> PListObjectItem
 fileReferenceItem fr = fileReferenceId fr ~> dict
diff --git a/Text/PList/PrettyPrint.hs b/Text/PList/PrettyPrint.hs
--- a/Text/PList/PrettyPrint.hs
+++ b/Text/PList/PrettyPrint.hs
@@ -7,11 +7,11 @@
 
 import Kit.Xcode.Common
 
-import "mtl" Control.Monad.Writer (Writer, runWriter, tell)
+import "mtl" Control.Monad.Writer (MonadWriter, Writer, runWriter, tell)
 import "mtl" Control.Monad.State (StateT, get, put, runStateT)
 
 pp :: PListFile -> String
-pp (PListFile charset root value) = "// " ++ charset ++ "\n" ++ printValue (obj value) ++ "\n"
+pp (PListFile charset _ value) = "// " ++ charset ++ "\n" ++ printValue (obj value) ++ "\n"
 
 printItem :: PListObjectItem -> [Char]
 printItem (PListObjectItem k v) = k ++ " = " ++ printValue v ++ ";\n"
@@ -41,15 +41,19 @@
                 ("rootObject", FlatStr root)
               ]
 
+seedKeys :: [UUID]
 seedKeys = map uuid [50000..]
 
 printFlat :: FlatDocument -> String
 printFlat = printFlatItem . FlatObj
 
+quoteIf :: String -> String
 quoteIf a = if quotable a then quote a else a
 
+xxx :: ([Char], FlatItem) -> [Char]
 xxx (k,v) = k ++ " = " ++ printFlatItem v ++ ";\n"
 
+printFlatItem :: FlatItem -> String
 printFlatItem (FlatStr a) = quoteIf a
 printFlatItem (FlatArr xs) = "(" ++ join (intersperse ", " $ map quoteIf xs) ++ ")"
 printFlatItem (FlatObj kvs) = "{\n" ++ (kvs >>= (\x -> "  " ++ xxx x)) ++ "}\n"
@@ -93,10 +97,9 @@
   put xs
   return x
 
-writeToRef ref obj = tell [(ref, obj)]
-
+writeObj :: FlatItem -> StateT [String] (Writer [(String, FlatItem)]) String
 writeObj o = do
   r <- readRef
-  writeToRef r o
+  tell [(r,o)]
   return r
 
diff --git a/kit.cabal b/kit.cabal
--- a/kit.cabal
+++ b/kit.cabal
@@ -1,5 +1,5 @@
 name:           kit
-version:        0.7.9
+version:        0.7.10
 cabal-version:  >=1.6
 build-type:     Simple
 license:        BSD3
@@ -15,29 +15,26 @@
   main-is:        Main.hs
   buildable:      True
   build-depends:  base >=3 && <5,
-                  Glob >= 0.5.1 && < 6, 
+                  Glob >= 0.7.1, 
                   attoparsec,
-                  HTTP,
                   ansi-terminal >= 0.5.5,
-                  bytestring -any, 
                   cabal-file-th >= 0.2.2,
-                  cmdargs >= 0.6.2,
+                  cmdargs >= 0.9.6,
                   containers -any, 
+                  errors >= 1.3.1,
                   yaml,
                   directory -any, 
                   filepath -any, 
                   mtl -any,
-                  network -any, 
                   process -any,
-                  template-haskell,
                   unordered-containers,
                   text,
-                  unix 
+                  unix
 
   hs-source-dirs: .
   other-modules:  Kit.Spec Kit.Main Kit.Package Kit.Project Kit.Repository Kit.Util Kit.Xcode.Builder
                   Kit.Xcode.Common Kit.Xcode.ProjectFileTemplate Kit.Xcode.XCConfig Text.PList Text.PList.PrettyPrint
-                  Kit.Contents Kit.Commands Kit.CmdArgs Kit.Util.FSAction Kit.WorkingCopy Kit.FilePath
+                  Kit.Contents Kit.Commands Kit.CmdArgs Kit.Util.FSAction Kit.WorkingCopy Kit.AbsolutePath
                   Kit.Dependency
   Ghc-options:    -Wall
 
