diff --git a/Kit/Main.hs b/Kit/Main.hs
--- a/Kit/Main.hs
+++ b/Kit/Main.hs
@@ -23,7 +23,7 @@
   import Data.Data
   import Data.Typeable
 
-  appVersion = "0.3"
+  appVersion = "0.5"
 
   defaultLocalRepoPath = do
       home <- getHomeDirectory
@@ -31,7 +31,7 @@
   defaultLocalRepository = fmap fileRepo defaultLocalRepoPath
 
   handleFails :: Either KitError a -> IO ()
-  handleFails = either (putStrLn . ("kit error: " ++)) (\x -> return ())
+  handleFails = either (putStrLn . ("kit error: " ++)) (const $ return ())
 
   run f = runErrorT f >>= handleFails
 
@@ -42,7 +42,7 @@
               puts $ "Dependencies: " ++ (stringJoin ", " $ map kitFileName deps)
               liftIO $ mapM (installKit repo) deps
               puts " -> Generating XCode project..."
-              liftIO $ generateXCodeProject deps
+              generateXCodeProject deps
               puts "Kit complete. You may need to restart XCode for it to pick up any changes."
                 where p x = liftIO $ print x
                       puts x = liftIO $ putStrLn x
diff --git a/Kit/Model.hs b/Kit/Model.hs
--- a/Kit/Model.hs
+++ b/Kit/Model.hs
@@ -7,7 +7,9 @@
   data KitSpec = KitSpec {
     specKit :: Kit,
     specDependencies :: [Kit],
-    specSourceDir :: FilePath
+    specSourceDirectory :: FilePath,
+    specTestDirectory :: FilePath,
+    specLibDirectory :: FilePath
   } deriving (Show, Read)
 
   type Version = String
@@ -24,7 +26,7 @@
   kitConfigFile kit = kitFileName kit </> (kitName kit ++ ".xcconfig")
 
   defaultSpecForKit :: Kit -> KitSpec
-  defaultSpecForKit kit = KitSpec kit [] "src"
+  defaultSpecForKit kit = KitSpec kit [] "src" "test" "lib" -- TODO make this and the json reading use the same defaults
 
   instance JSON Kit where
       showJSON kit = makeObj
@@ -33,8 +35,7 @@
           ]
 
       readJSON (JSObject obj) = Kit <$> f "name" <*> f "version"
-        where f x = mLookup x jsonObjAssoc >>= readJSON
-              jsonObjAssoc = fromJSObject obj
+        where f x = f' obj x 
 
   instance JSON KitSpec where
       showJSON spec = makeObj
@@ -44,12 +45,15 @@
           ]
           where kit = specKit spec
 
-      readJSON (JSObject obj) =
-          let myKit = Kit <$> f "name" <*> f "version"
-              -- myConfig = (KitConfiguration <$> )
-           in KitSpec <$> myKit <*> f "dependencies" <*> (f "sourceDir" <|> pure "src")
-        where f x = mLookup x jsonObjAssoc >>= readJSON
-              jsonObjAssoc = fromJSObject obj
+      readJSON js@(JSObject obj) =
+              KitSpec <$> readJSON js 
+                      <*> (f "dependencies" <|> pure []) 
+                      <*> (f "source-directory" <|> pure "src")
+                      <*> (f "test-directory" <|> pure "test")
+                      <*> (f "lib-directory" <|> pure "lib")
+        where f x = f' obj x
+
+  f' obj x = mLookup x (fromJSObject obj) >>= readJSON
 
   mLookup :: Monad m => String -> [(String, b)] -> m b
   mLookup a as = maybe (fail $ "No such element: " ++ a) return (lookup a as)
diff --git a/Kit/Package.hs b/Kit/Package.hs
--- a/Kit/Package.hs
+++ b/Kit/Package.hs
@@ -13,14 +13,17 @@
   {-
     Package format
      src/ | configurable source dir
-     test/
+     test/ | test directory
+     lib/ | lib directory
+     *.xcconfig
+     *.pch
      KitSpec
      *.codeproj
   -}
 
   fileBelongsInPackage :: KitSpec -> FilePath -> Bool
   fileBelongsInPackage config fp = let
-    a = elem fp [specSourceDir config, "test", "KitSpec"]
+    a = elem fp [specSourceDirectory config, specTestDirectory config, specLibDirectory config, "KitSpec"]
     b = "xcodeproj" `isSuffixOf` fp
     c = "xcconfig" `isSuffixOf` fp
     d = ".pch" `isSuffixOf` fp
diff --git a/Kit/Project.hs b/Kit/Project.hs
--- a/Kit/Project.hs
+++ b/Kit/Project.hs
@@ -36,40 +36,49 @@
 
   -- Represents an extracted project
   -- Headers, Sources, Config, Prefix content
-  data KitContents = KitContents { contentHeaders :: [String], contentSources :: [String], contentConfig :: Maybe XCConfig, contentPrefix :: Maybe String }
+  data KitContents = KitContents { contentHeaders :: [FilePath], contentSources :: [FilePath], contentLibs :: [FilePath], contentConfig :: Maybe XCConfig, contentPrefix :: Maybe String }
 
-  readKitContents :: Kit -> IO KitContents
-  readKitContents kit  =
-    let kitDir = kitFileName kit
-        find tpe = glob ((kitDir </> "src/**/*") ++ tpe)
-        headers = find ".h"
-        sources = fmap join $ T.sequence [find ".m", find ".mm", find ".c"]
+  readKitContents :: KitSpec -> IO KitContents
+  readKitContents spec  =
+    let kit = specKit spec
+        kitDir = kitFileName kit
+        find dir tpe = glob ((kitDir </> dir </> "**/*") ++ tpe)
+        findSrc = find $ specSourceDirectory spec
+        headers = findSrc ".h"
+        sources = fmap join $ T.sequence [findSrc ".m", findSrc ".mm", findSrc ".c"]
+        libs = find (specLibDirectory spec) ".a" 
         config = readConfig kit
         prefix = readHeader kit
-    in  KitContents <$> headers <*> sources <*> config <*> prefix
+    in  KitContents <$> headers <*> sources <*> libs <*> config <*> prefix
 
-  generateXCodeProject :: [Kit] -> IO ()
+  generateXCodeProject :: [Kit] -> KitIO ()
   generateXCodeProject deps = do
-    mkdir_p kitDir
+    liftIO $ mkdir_p kitDir
+    specs <- forM deps $ \kit -> readSpec (kitDir </> kitFileName kit </> "KitSpec")  
     inDirectory kitDir $ do
-      kitsContents <- T.for deps readKitContents
-      createProjectFile kitsContents
-      createHeader kitsContents
-      createConfig kitsContents
+      kitsContents <- forM specs (liftIO . readKitContents)
+      liftIO $ createProjectFile kitsContents
+      liftIO $ createHeader kitsContents
+      liftIO $ createConfig kitsContents specs
     where kitFileNames = map kitFileName deps
+          sourceDirs specs = specs >>= (\spec -> [
+              kitDir </> (kitFileName . specKit $ spec) </> specSourceDirectory spec, 
+              (kitFileName . specKit $ spec) </> specSourceDirectory spec
+            ])
           createProjectFile cs = do
             let headers = cs >>= contentHeaders
             let sources = cs >>= contentSources
+            let libs = cs >>= contentLibs
             mkdir_p projectDir
-            writeFile projectFile $ buildXCodeProject headers sources
+            writeFile projectFile $ buildXCodeProject headers sources libs
           createHeader cs = do
             let headers = mapMaybe contentPrefix cs
             let combinedHeader = stringJoin "\n" headers
             writeFile prefixFile $ prefixDefault ++ combinedHeader ++ "\n"
-          createConfig cs = do
+          createConfig cs specs = do
             let configs = mapMaybe contentConfig cs
             let combinedConfig = multiConfig "KitConfig" configs
-            let kitHeaders = "HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS) " ++ (stringJoin " "  $ kitFileNames >>= (\x -> [kitDir </> x </> "src", x </> "src"]))
+            let kitHeaders = "HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS) " ++ (stringJoin " " $ sourceDirs specs)
             let prefixHeaders = "GCC_PRECOMPILE_PREFIX_HEADER = YES\nGCC_PREFIX_HEADER = $(SRCROOT)/KitDeps_Prefix.pch\n"
             writeFile xcodeConfigFile $ kitHeaders ++ "\n" ++  prefixHeaders ++ "\n" ++ configToString combinedConfig
             writeFile kitUpdateMakeFilePath kitUpdateMakeFile
diff --git a/Kit/Repository.hs b/Kit/Repository.hs
--- a/Kit/Repository.hs
+++ b/Kit/Repository.hs
@@ -1,5 +1,4 @@
 {-
-
   Exposes the repositories.
   Allows you to:
     * copy down kit packages (getKit)
diff --git a/Kit/Util.hs b/Kit/Util.hs
--- a/Kit/Util.hs
+++ b/Kit/Util.hs
@@ -53,12 +53,12 @@
     when exists $ removeDirectoryRecursive directory
     mkdir_p directory
 
-  inDirectory :: FilePath -> IO a -> IO a
+  inDirectory :: MonadIO m => FilePath -> m a -> m a
   inDirectory dir actions = do
-    cwd <- getCurrentDirectory
-    setCurrentDirectory dir
+    cwd <- liftIO $ getCurrentDirectory
+    liftIO $ setCurrentDirectory dir
     v <- actions
-    setCurrentDirectory cwd
+    liftIO $ setCurrentDirectory cwd
     return v
 
   glob :: String -> IO [String]
@@ -66,5 +66,4 @@
 
   stringJoin :: Monoid a => a -> [a] -> a
   stringJoin x = mconcat . intersperse x
-
 
diff --git a/Kit/XCode/Builder.hs b/Kit/XCode/Builder.hs
--- a/Kit/XCode/Builder.hs
+++ b/Kit/XCode/Builder.hs
@@ -1,148 +1,106 @@
 
 module Kit.XCode.Builder (buildXCodeProject) where
-
   import Data.Monoid
-  import Data.List
   import Kit.XCode.Common
-  import Kit.XCode.ProjectFile
+  import Kit.XCode.ProjectFileTemplate
+  import Text.PList
   import Kit.Util
 
+  import Debug.Trace
+
+  import System.FilePath.Posix (dropFileName)
+  import Data.List (nub)
+
   createBuildFile :: Integer -> FilePath -> PBXBuildFile
   createBuildFile i path = PBXBuildFile uuid1 $ PBXFileReference uuid2 path
     where uuid1 = uuid i
           uuid2 = uuid $ i + 10000000
 
-  buildXCodeProject :: [FilePath] -> [FilePath] -> String
-  buildXCodeProject headers sources =
-      projectPbxProj bfs frs classes hs srcs
+  buildXCodeProject :: [FilePath] -> [FilePath] -> [FilePath] -> String
+  buildXCodeProject headers sources libs = show $ makeProjectPList bfs frs classes hs srcs xxx fg libDirs
     where
+      libDirs = nub $ map dropFileName libs 
       sourceStart = toInteger (length headers + 1)
+      libStart = toInteger (length headers + length sources + 1)
       headerBuildFiles = zipWith createBuildFile [1..] headers
       sourceBuildFiles = zipWith createBuildFile [sourceStart..] sources
-      allBuildFiles = (sourceBuildFiles ++ headerBuildFiles)
+      libBuildFiles = zipWith createBuildFile [libStart..] libs
+      allBuildFiles = (sourceBuildFiles ++ headerBuildFiles ++ libBuildFiles)
       bfs = buildFileSection allBuildFiles
       frs = fileReferenceSection $ map buildFileReference allBuildFiles
       classes = classesSection $ map buildFileReference (sourceBuildFiles ++ headerBuildFiles)
-      hs = headersSection headerBuildFiles
-      srcs = sourcesSection sourceBuildFiles
-
-  xxx :: FilePath -> UUID -> UUID -> PBXBuildFile
-  xxx fp buildId fileId = PBXBuildFile buildId (PBXFileReference fileId fp)
-
-  -- 47021EC1117A7776003DB5B7 /* motive.m in Sources */ = {isa = PBXBuildFile; fileRef = 47021EBF117A7776003DB5B7 /* motive.m */; };
-  buildFileItem :: PBXBuildFile -> String
-  buildFileItem bf = lineItem i comment dict
-    where fr = buildFileReference bf
-          i = buildFileId bf
-          comment = let ft Unknown = "Unknown"
-                        ft Header = "Headers"
-                        ft Source = "Sources"
-                        bit = ft . fileType . fileReferencePath $ fr
-                    in fileReferenceName fr ++ " in " ++ bit
-          dict = [
-              "isa" ~> "PBXBuildFile",
-              "fileRef" ~> (fileReferenceId fr ++ " /* " ++ fileReferenceName fr ++ " */")
-            ]
-
-  fileTypeBit :: FileType -> String
-  fileTypeBit Header = "sourcecode.c.h"
-  fileTypeBit Source = "sourcecode.c.objc"
-  fileTypeBit Unknown = "sourcecode.unknown"
-
-  -- 47021EBE117A7776003DB5B7 /* motive.h */ = {isa = PBXFileReference; fileEncoding = 4;
-  -- lastKnownFileType = sourcecode.c.h; name = motive.h; path = "kits/motive-0.1/src/motive.h"; sourceTree = "<group>"; };
-  fileReferenceItem :: PBXFileReference -> String
-  fileReferenceItem fr = lineItem fid fileName dict
-    where
-      fid = fileReferenceId fr
-      path = fileReferencePath fr
-      fileName = fileReferenceName fr
-      dict = [
-          "isa" ~> "PBXFileReference",
-          "fileEncoding" ~> "4",
-          "lastKnownFileType" ~> (fileTypeBit . fileType $ fileName),
-          "name" ~> show fileName,
-          "path" ~> show path,
-          "sourceTree" ~> show "<group>"
-        ]
-
-  layoutSection :: String -> [String] -> String
-  layoutSection name body = let
-      front  = "/* Begin " ++ name ++ " section */"
-      middle = map ("    " ++) body
-      back   = "/* End " ++ name ++ " section */"
-      in mconcat $ intersperse "\n" ((front : middle) ++ [back])
+      hs = headersBuildPhase headerBuildFiles
+      srcs = sourcesBuildPhase sourceBuildFiles
+      xxx = frameworksBuildPhase $ traceShow libBuildFiles libBuildFiles
+      fg = frameworksGroup $ map buildFileReference libBuildFiles
 
-  buildFileSection :: [PBXBuildFile] -> String
-  buildFileSection bfs = layoutSection "PBXBuildFile" (map buildFileItem bfs ++ [
-      "4728C530117C02B10027D7D1 /* Kit.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 4728C52F117C02B10027D7D1 /* Kit.xcconfig */; };",
-      "AA747D9F0F9514B9006C5449 /* KitDeps_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* KitDeps_Prefix.pch */; };",
-      "AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };"
+  buildFileSection :: [PBXBuildFile] -> [PListObjectItem]
+  buildFileSection bfs = (map buildFileItem bfs ++ [
+      "4728C530117C02B10027D7D1" ~> buildFile kitConfigRefUUID,
+      "AA747D9F0F9514B9006C5449" ~> buildFile "AA747D9E0F9514B9006C5449",
+      "AACBBE4A0F95108600F1A2B1" ~> buildFile "AACBBE490F95108600F1A2B1"
     ])
 
-  fileReferenceSection :: [PBXFileReference] -> String
-  fileReferenceSection refs = layoutSection "PBXFileReference" (map fileReferenceItem refs ++ [
-  		"4728C52F117C02B10027D7D1 /* Kit.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Kit.xcconfig; sourceTree = \"<group>\"; };",
-      "AA747D9E0F9514B9006C5449 /* KitDeps_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KitDeps_Prefix.pch; sourceTree = SOURCE_ROOT; };",
-	    "AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };",
-	    "D2AAC07E0554694100DB518D /* libKitDeps.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKitDeps.a; sourceTree = BUILT_PRODUCTS_DIR; };"
-    ])
+  fileReferenceSection :: [PBXFileReference] -> [PListObjectItem]
+  fileReferenceSection refs = map fileReferenceItem refs ++ [
+  		kitConfigRefUUID ~> obj [ 
+        "isa" ~> val "PBXFileReference",
+        "fileEncoding" ~> val "4",
+        "lastKnownFileType" ~> val "text.xcconfig",
+        "path" ~> val "Kit.xcconfig",
+        "sourceTree" ~> val "<group>"
+        ],
+      "AA747D9E0F9514B9006C5449" ~> obj [
+        "isa" ~> val "PBXFileReference",
+        "fileEncoding" ~> val "4",
+        "lastKnownFileType" ~> val "sourcecode.c.h",
+        "path" ~> val "KitDeps_Prefix.pch",
+        "sourceTree" ~> val "SOURCE_ROOT"
+        ],
+      "AACBBE490F95108600F1A2B1" ~> obj [
+        "isa" ~> val "PBXFileReference",
+        "lastKnownFileType" ~> val "wrapper.framework",
+        "name" ~> val "Foundation.framework", 
+        "path" ~> val "System/Library/Frameworks/Foundation.framework",
+        "sourceTree" ~> val "SDKROOT"
+        ],
+      productRefUUID ~> obj [
+        "isa" ~> val "PBXFileReference",
+        "explicitFileType" ~> val "archive.ar",
+        "includeInIndex" ~> val "0",
+        "path" ~> val "libKitDeps.a",
+        "sourceTree" ~> val "BUILT_PRODUCTS_DIR"
+      ]
+    ]
 
-  classesSection :: [PBXFileReference] -> String
-  classesSection files = lineItem "08FB77AEFE84172EC02AAC07" "Classes" dict
-	    where dict = [
-            	    "isa" ~> "PBXGroup",
-            	    "children" ~> ("(" ++ (mconcat (intersperse "," (map fileReferenceId files))) ++ ",)"),
-            	    "name" ~> "Classes",
-            	    "sourceTree" ~> show "<group>"
-	                ]
+  classesSection :: [PBXFileReference] -> PListObjectItem 
+  classesSection files = classesGroupUUID ~> group "Classes" (map (val . fileReferenceId) files)
 	
-	{-/* Begin PBXHeadersBuildPhase section */
-  		D2AAC07A0554694100DB518D /* Headers */ = {
-  			isa = PBXHeadersBuildPhase;
-  			buildActionMask = 2147483647;
-  			files = (
-  				AA747D9F0F9514B9006C5449 /* KitDeps_Prefix.pch in Headers */,
-  				4791C244117A7893001EB278 /* motive.h in Headers */,
-  			);
-  			runOnlyForDeploymentPostprocessing = 0;
-  		};
-  /* End PBXHeadersBuildPhase section */-}
-  headersSection :: [PBXBuildFile] -> String
-  headersSection bfs = layoutSection "PBXHeadersBuildPhase" [lineItem "D2AAC07A0554694100DB518D" "Headers" [
-    "isa" ~> "PBXHeadersBuildPhase",
-    "buildActionMask" ~> "2147483647",
-    "files" ~> ("(" ++ (stringJoin "," $ prefixPchUUID : map buildFileId bfs) ++ ",)"),
-    "runOnlyForDeploymentPostprocessing" ~> "0"
-	  ]]
-	  where prefixPchUUID = "AA747D9F0F9514B9006C5449"
+  frameworksGroup :: [PBXFileReference] -> PListObjectItem
+  frameworksGroup files = frameworksGroupUUID ~> group "Frameworks" (val "AACBBE490F95108600F1A2B1" :  (map (val . fileReferenceId) files))
+
+  frameworksBuildPhase :: [PBXBuildFile] -> PListObjectItem  
+  frameworksBuildPhase libs = frameworksBuildPhaseUUID ~> obj [
+            "isa" ~> val "PBXFrameworksBuildPhase",
+            "buildActionMask" ~> val "2147483647",
+            "files" ~> arr (val "AACBBE4A0F95108600F1A2B1" : map (val . buildFileId) libs),
+            "runOnlyForDeploymentPostprocessing" ~> val "0"
+          ]
+
+  headersBuildPhase :: [PBXBuildFile] -> PListObjectItem
+  headersBuildPhase bfs = headersBuildPhaseUUID ~> obj [
+    "isa" ~> val "PBXHeadersBuildPhase",
+    "buildActionMask" ~> val "2147483647",
+    "files" ~> arr (val "AA747D9F0F9514B9006C5449" : map (val . buildFileId) bfs),
+    "runOnlyForDeploymentPostprocessing" ~> val "0"
+	  ]
 	
-	{-
-    /* Begin PBXSourcesBuildPhase section */
-    		D2AAC07B0554694100DB518D /* Sources */ = {
-    			isa = PBXSourcesBuildPhase;
-    			buildActionMask = 2147483647;
-    			files = (
-    				47021EC1117A7776003DB5B7 /* motive.m in Sources */,
-    			);
-    			runOnlyForDeploymentPostprocessing = 0;
-    		};
-    /* End PBXSourcesBuildPhase section */
-	-}
-  sourcesSection :: [PBXBuildFile] -> String
-  sourcesSection bfs = layoutSection "PBXSourcesBuildPhase" [lineItem "D2AAC07B0554694100DB518D" "Sources" [
-    "isa" ~> "PBXSourcesBuildPhase",
-    "buildActionMask" ~> "2147483647",
-    "files" ~> ("(" ++ (stringJoin "," $ map buildFileId bfs) ++ ",)"),
-    "runOnlyForDeploymentPostprocessing" ~> "0"
-    ]]
+  sourcesBuildPhase :: [PBXBuildFile] -> PListObjectItem
+  sourcesBuildPhase bfs = sourcesBuildPhaseUUID ~> obj [
+    "isa" ~> val "PBXSourcesBuildPhase",
+    "buildActionMask" ~> val "22147483647147483647",
+    "files" ~>  arr (map (val . buildFileId) bfs),
+    "runOnlyForDeploymentPostprocessing" ~> val "0"
+    ]
 
-  testBuilder = let
-    header = PBXFileReference "1" "fk/fk.h"
-    source = PBXFileReference "2" "fk/fk.m"
-    headerBF = PBXBuildFile "10" header
-    sourceBF = PBXBuildFile "20" source
-      in do
-          putStrLn . buildFileSection $  [headerBF, sourceBF]
-          putStrLn . fileReferenceSection $ [header, source]
 
diff --git a/Kit/XCode/Common.hs b/Kit/XCode/Common.hs
--- a/Kit/XCode/Common.hs
+++ b/Kit/XCode/Common.hs
@@ -2,44 +2,68 @@
   import Data.Monoid
   import Data.List
   import System.FilePath.Posix
-          
+  
+  import Text.PList
+
+  
   type UUID = String
-  type Dict = [(String, String)]
   
-  data FileType = Header | Source | Unknown
+  data FileType = Header | Source | Archive | Unknown
   
   fileType :: String -> FileType
   fileType x | ".h" `isSuffixOf` x = Header
   fileType x | ".m" `isSuffixOf` x = Source
   fileType x | ".mm" `isSuffixOf` x = Source
   fileType x | ".c" `isSuffixOf` x = Source
+  fileType x | ".a" `isSuffixOf` x = Archive
   fileType _ = Unknown
-  
-  (~>) = (,)
-  
+
+  fileTypeBit :: FileType -> String
+  fileTypeBit Header = "sourcecode.c.h"
+  fileTypeBit Source = "sourcecode.c.objc"
+  fileTypeBit Unknown = "sourcecode.unknown"
+  fileTypeBit Archive = "archive.ar"
+
   data PBXBuildFile = PBXBuildFile {
-    buildFileId :: String,
+    buildFileId :: UUID,
     buildFileReference :: PBXFileReference
-  }
+  } deriving (Eq, Show)
   
   data PBXFileReference = PBXFileReference {
-    fileReferenceId :: String,
+    fileReferenceId :: UUID,
     fileReferencePath :: String
-  }
+  } deriving (Eq, Show)
   
+  group name children = obj [
+      "isa" ~> val "PBXGroup",
+      "name" ~> val name,
+      "sourceTree" ~> val "<group>",
+      "children" ~> arr children
+    ]
+
+  buildFile refUUID = obj [ "isa" ~> val "PBXBuildFile", "fileRef" ~> val refUUID ]
+
+  buildFileItem :: PBXBuildFile -> PListObjectItem 
+  buildFileItem bf = buildFileId bf ~> buildFile (fileReferenceId . buildFileReference $ bf) 
+
+  fileReferenceItem :: PBXFileReference -> PListObjectItem
+  fileReferenceItem fr = (fileReferenceId fr) ~> dict
+    where
+      fileName = fileReferenceName fr
+      dict = obj [
+          "isa" ~> val "PBXFileReference",
+          "fileEncoding" ~> val "4",
+          "lastKnownFileType" ~> val (fileTypeBit . fileType $ fileName),
+          "name" ~> val fileName,
+          "path" ~> (val $ fileReferencePath fr),
+          "sourceTree" ~> val "<group>"
+        ]
+
+
   fileReferenceName = takeFileName . fileReferencePath
   
-  lineItem :: UUID -> String -> Dict -> String
-  lineItem uuid comment dict = uuid ++ " /* " ++ comment ++ " */ = " ++ buildDict dict ++ ";"
-  
-  buildDict :: Dict -> String
-  buildDict ps = g . mconcat . map (\x -> fst x ++ " = " ++ snd x ++ "; ") $ ps
-    where g s = "{"  ++ s ++ "}"
-  
   uuid :: Integer -> UUID
   uuid i = let
-      s = show i
-      lengthS = length s
-      pad = 24 - lengthS
-    in
-      replicate pad '0' ++ s 
+       s = show i
+       pad = 24 - length s
+    in replicate pad '0' ++ s 
diff --git a/Kit/XCode/OldPList.hs b/Kit/XCode/OldPList.hs
deleted file mode 100644
--- a/Kit/XCode/OldPList.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-# LANGUAGE TypeSynonymInstances #-}
-module Kit.XCode.OldPList where
-
-import Data.List
-
-class AsPListType a where
-    asPListType :: a -> PListType
-
-instance AsPListType PListType where
-    asPListType = id
-
-data PListType = PListValue String
-               | PListArray [PListType]
-               | PListObject [(String, PListType)]
-
-val = PListValue
-arr = PListArray
-obj = PListObject
-
-data PListFile = PListFile { pListFileCharset :: String, pListFileValue :: PListType }
-
-quote s = "\"" ++ s ++ "\""
-quotable s = or $ map (\x -> x `isInfixOf` s) ["-", "<", ">", " "]
-
-
-instance Show PListType where
-
-    show (PListValue a) = if (quotable a) then quote a else a
-    show (PListArray xs) = "(" ++ (map ((++ ",") . show) xs >>= id) ++ ")"
-    show (PListObject kvs) = "{" ++ (kvs >>= f) ++ "}"
-                                where f (k, v) = k ++ " = " ++ show v ++ ";"
-
-(~=~) = (,)
-
-
-projectFile = PListFile "!$*UTF8*$!" $ PListObject [
-        "archiveVersion" ~=~ PListValue "1",
-        "classes" ~=~ PListObject [],
-        "objectVersion" ~=~ PListValue "45",
-        "objects" ~=~ PListObject []
-    ]
-
diff --git a/Kit/XCode/PBXProject.hs b/Kit/XCode/PBXProject.hs
deleted file mode 100644
--- a/Kit/XCode/PBXProject.hs
+++ /dev/null
@@ -1,101 +0,0 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-module Kit.XCode.PBXProject where
-
-import Kit.XCode.OldPList
-import Control.Monad.State
-import Control.Monad.Writer
-import qualified Data.Map as M
-
-type UUID = String
-
-data UUIDValue = UUIDProject PBXProject | UUIDGroup PBXGroup deriving (Eq, Show, Ord)
-
-data UUIDState = UUIDState {
-    unusedUUIDs :: [UUID]
-  , knownObjects :: M.Map UUIDValue UUID
-}
-
-lookupObject :: UUIDValue -> State UUIDState UUID --UUIDState -> (UUIDState, UUIValue)
-lookupObject v = do
-    s <- get
-    let o = M.lookup v $ knownObjects s
-    maybe (insertObject v) return o
-     where insertObject v = do
-                              s@(UUIDState (u:uuids) objects) <- get
-                              put $ UUIDState uuids (M.insert v u objects)
-                              return u
-
-data PBXProject = PBXProject {
-    projectConfigurationList :: XCConfigurationList
-  , projectGroups :: [PBXGroup]
-  , projectName :: String
-  , targets :: [PBXNativeTarget]
-} deriving (Eq, Show, Ord)
-
-data PBXNativeTarget = PBXNativeTarget {
-    targetConfigurationList :: XCConfigurationList
-  , targetBuildPhases :: [PBXBuildPhase]
-} deriving (Eq, Show, Ord)
-
-data PBXBuildPhase = PBXBuildPhase deriving (Eq, Show, Ord)
-
-data XCConfigurationList = XCConfigurationList {
-  configurationsList :: [XCBuildConfiguration]
-} deriving (Eq, Show, Ord)
-
-data PBXGroup = PBXGroup {
-    groupChildren :: [PBXGroup]
-  , groupChildrenExtra :: [UUID]
-  , groupName :: String
-  , groupSourceTree :: String
-} deriving (Eq, Show, Ord)
-
-data XCBuildConfiguration = XCBuildConfiguration deriving (Eq, Show, Ord)
-
-instance ProjectPListItem PBXGroup where
-  writeEntry group = do
-    childUUIDs <- mapM writeEntry (groupChildren group)
-    write $ obj [
-          "isa" ~=~ val "PBXGroup"
-        , "name" ~=~ (val . groupName) group
-        , "sourceTree" ~=~ (val . groupSourceTree) group
-        , "children" ~=~ (arr $ map val (childUUIDs ++ groupChildrenExtra group))
-      ]
-
-type PLObjects = [(UUID, PListType)]
--- Consume UUIDs from state, write out other objects to be added to the plist
-newtype PL a = PL { unPL :: WriterT PLObjects (State [UUID]) a }
-              deriving (Monad, MonadState [UUID], MonadWriter PLObjects)
-
-class ProjectPListItem a where
-  writeEntry :: a -> PL UUID
-
-popS = do
-  (x:xs) <- get
-  put xs
-  return x
-
-write blah = do
-  uuid <- popS
-  tell [(uuid, blah)]
-  return uuid
-
-f :: M.Map UUID a -> a -> (M.Map UUID a, UUID)
-f = undefined
-
-instance ProjectPListItem PBXProject where
-  writeEntry project = do
-    config <- write $ val "TODO"
-    productGroupUUID <- writeEntry (PBXGroup [] [] "Products" "<group>")
-    mainGroupUUID <- writeEntry (PBXGroup [] [productGroupUUID] (projectName project) "<group>")
-    write $ obj [
-        "isa" ~=~ val "PBXProject"
-      , "buildConfigurationList" ~=~ val config
-      , "compatibilityVersion" ~=~ val "Xcode 3.1"
-      , "hasScannedForEncodings" ~=~ val "1"
-      , "mainGroup" ~=~ val mainGroupUUID
-      , "productRefGroup" ~=~ val productGroupUUID
-      , "projectDirPath" ~=~ val ""
-      , "projectRoot" ~=~ val ""
-      , "targets" ~=~ arr []
-     ]
diff --git a/Kit/XCode/ProjectFile.hs b/Kit/XCode/ProjectFile.hs
deleted file mode 100644
--- a/Kit/XCode/ProjectFile.hs
+++ /dev/null
@@ -1,242 +0,0 @@
-{-
-
-  Constant sections of the project file
--}
-module Kit.XCode.ProjectFile (projectPbxProj) where
-  nl a b = a ++ "\n" ++ b
-
-  projectPbxProj bfs fileRefsSection classes headers sources =
-      top `nl` bfs `nl` fileRefsSection `nl` next1 `nl` classes `nl` next2 `nl` headers `nl` next3 `nl` sources `nl` bottom
-
-  top = "// !$*UTF8*$!" `nl`
-    "{" `nl`
-    " archiveVersion = 1;" `nl`
-    " classes = {" `nl`
-    " };" `nl`
-    " objectVersion = 45;" `nl`
-    " objects = {"
-
-  next1 = "/* Begin PBXFrameworksBuildPhase section */" `nl`
-    		"D2AAC07C0554694100DB518D /* Frameworks */ = {" `nl`
-    			"isa = PBXFrameworksBuildPhase;" `nl`
-    			"buildActionMask = 2147483647;" `nl`
-    			"files = (" `nl`
-    				"AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */," `nl`
-    			");" `nl`
-    			"runOnlyForDeploymentPostprocessing = 0;" `nl`
-    		"};" `nl`
-    "/* End PBXFrameworksBuildPhase section */" `nl`
-    "" `nl`
-    "/* Begin PBXGroup section */" `nl`
-    		"034768DFFF38A50411DB9C8B /* Products */ = {" `nl`
-    			"isa = PBXGroup;" `nl`
-    			"children = (" `nl`
-    				"D2AAC07E0554694100DB518D /* libKitDeps.a */," `nl`
-    			");" `nl`
-    			"name = Products;" `nl`
-    			"sourceTree = \"<group>\";" `nl`
-    		"};" `nl`
-    		"0867D691FE84028FC02AAC07 /* KitDeps */ = {" `nl`
-    			"isa = PBXGroup;" `nl`
-    			"children = (" `nl`
-    				"08FB77AEFE84172EC02AAC07 /* Classes */," `nl`
-    				"32C88DFF0371C24200C91783 /* Other Sources */," `nl`
-    				"0867D69AFE84028FC02AAC07 /* Frameworks */," `nl`
-    				"034768DFFF38A50411DB9C8B /* Products */," `nl`
-    				"4728C52F117C02B10027D7D1 /* Kit.xcconfig */," `nl`
-    			");" `nl`
-    			"name = KitDeps;" `nl`
-    			"sourceTree = \"<group>\";" `nl`
-    		"};" `nl`
-    		"0867D69AFE84028FC02AAC07 /* Frameworks */ = {" `nl`
-    			"isa = PBXGroup;" `nl`
-    			"children = (" `nl`
-    				"AACBBE490F95108600F1A2B1 /* Foundation.framework */," `nl`
-    			");" `nl`
-    			"name = Frameworks;" `nl`
-    			"sourceTree = \"<group>\";" `nl`
-    		"};"
-    		
-  next2 = "32C88DFF0371C24200C91783 /* Other Sources */ = {" `nl`
-        			"isa = PBXGroup;" `nl`
-        			"children = (" `nl`
-        				"AA747D9E0F9514B9006C5449 /* KitDeps_Prefix.pch */," `nl`
-        			");" `nl`
-        			"name = \"Other Sources\";" `nl`
-        			"sourceTree = \"<group>\";" `nl`
-        		"};" `nl`
-        "/* End PBXGroup section */"
-
-  next3 = "/* Begin PBXNativeTarget section */" `nl`
-        		"D2AAC07D0554694100DB518D /* KitDeps */ = {" `nl`
-        			"isa = PBXNativeTarget;" `nl`
-        			"buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget \"KitDeps\" */;" `nl`
-        			"buildPhases = (" `nl`
-        				"D2AAC07A0554694100DB518D /* Headers */," `nl`
-        				"D2AAC07B0554694100DB518D /* Sources */," `nl`
-        				"D2AAC07C0554694100DB518D /* Frameworks */," `nl`
-        			");" `nl`
-              "buildRules = (" `nl`
-        			");" `nl`
-        			"dependencies = (" `nl`
-        			");" `nl`
-        			"name = KitDeps;" `nl`
-        			"productName = KitDeps;" `nl`
-        			"productReference = D2AAC07E0554694100DB518D /* libKitDeps.a */;" `nl`
-        			"productType = \"com.apple.product-type.library.static\";" `nl`
-        		"};" `nl`
-        "/* End PBXNativeTarget section */" `nl`
-        "" `nl`
-        kitUpdateTarget `nl`
-        "/* End PBXLegacyTarget section */" `nl`
-        "/* Begin PBXProject section */" `nl`
-        		"0867D690FE84028FC02AAC07 /* Project object */ = {" `nl`
-        			"isa = PBXProject;" `nl`
-        			"buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject \"KitDepsCustom\" */;" `nl`
-        			"compatibilityVersion = \"Xcode 3.1\";" `nl`
-        			"hasScannedForEncodings = 1;" `nl`
-        			"mainGroup = 0867D691FE84028FC02AAC07 /* KitDeps */;" `nl`
-        			"productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;" `nl`
-        			"projectDirPath = \"\";" `nl`
-        			"projectRoot = \"\";" `nl`
-        			"targets = (" `nl`
-        				"D2AAC07D0554694100DB518D /* KitDeps */," `nl`
-        				"470E2D641287730A0084AE6F /* KitUpdate */," `nl`
-        			");" `nl`
-        		"};" `nl`
-        "/* End PBXProject section */"
-
-  bottom = "/* Begin XCBuildConfiguration section */" `nl`
-        		"1DEB921F08733DC00010E9CD /* Debug */ = {" `nl`
-        			"isa = XCBuildConfiguration;" `nl`
-        			"buildSettings = {" `nl`
-        				"ALWAYS_SEARCH_USER_PATHS = NO;" `nl`
-        				"ARCHS = \"$(ARCHS_STANDARD_32_BIT)\";" `nl`
-        				"COPY_PHASE_STRIP = NO;" `nl`
-        				"DSTROOT = /tmp/KitDeps.dst;" `nl`
-        				"GCC_DYNAMIC_NO_PIC = NO;" `nl`
-        				"GCC_ENABLE_FIX_AND_CONTINUE = YES;" `nl`
-        				"GCC_MODEL_TUNING = G5;" `nl`
-        				"GCC_OPTIMIZATION_LEVEL = 0;" `nl`
-        				"GCC_PRECOMPILE_PREFIX_HEADER = YES;" `nl`
-        				"GCC_PREFIX_HEADER = KitDeps_Prefix.pch;" `nl`
-        				"INSTALL_PATH = /usr/local/lib;" `nl`
-        				"PRODUCT_NAME = KitDeps;" `nl`
-        			"};" `nl`
-        			"name = Debug;" `nl`
-        		"};" `nl`
-        		"1DEB922008733DC00010E9CD /* Release */ = {" `nl`
-        			"isa = XCBuildConfiguration;" `nl`
-        			"buildSettings = {" `nl`
-        				"ALWAYS_SEARCH_USER_PATHS = NO;" `nl`
-        				"ARCHS = \"$(ARCHS_STANDARD_32_BIT)\";" `nl`
-        				"DSTROOT = /tmp/KitDeps.dst;" `nl`
-        				"GCC_MODEL_TUNING = G5;" `nl`
-        				"GCC_PRECOMPILE_PREFIX_HEADER = YES;" `nl`
-        				"GCC_PREFIX_HEADER = KitDeps_Prefix.pch;" `nl`
-        				"INSTALL_PATH = /usr/local/lib;" `nl`
-        				"PRODUCT_NAME = KitDeps;" `nl`
-        			"};" `nl`
-        			"name = Release;" `nl`
-        		"};" `nl`
-        		"1DEB922308733DC00010E9CD /* Debug */ = {" `nl`
-        			"isa = XCBuildConfiguration;" `nl`
-        			"baseConfigurationReference = 4728C52F117C02B10027D7D1 /* Kit.xcconfig */;" `nl`
-        			"buildSettings = {" `nl`
-        				"ARCHS = \"$(ARCHS_STANDARD_32_BIT)\";" `nl`
-        				"GCC_C_LANGUAGE_STANDARD = c99;" `nl`
-        				"GCC_OPTIMIZATION_LEVEL = 0;" `nl`
-        				"GCC_WARN_ABOUT_RETURN_TYPE = YES;" `nl`
-        				"GCC_WARN_UNUSED_VARIABLE = YES;" `nl`
-        				"OTHER_LDFLAGS = \"-ObjC\";" `nl`
-        				"PREBINDING = NO;" `nl`
-        				"SDKROOT = iphoneos;" `nl`
-        			"};" `nl`
-        			"name = Debug;" `nl`
-        		"};" `nl`
-        		"1DEB922408733DC00010E9CD /* Release */ = {" `nl`
-        			"isa = XCBuildConfiguration;" `nl`
-        			"baseConfigurationReference = 4728C52F117C02B10027D7D1 /* Kit.xcconfig */;" `nl`
-        			"buildSettings = {" `nl`
-        				"ARCHS = \"$(ARCHS_STANDARD_32_BIT)\";" `nl`
-        				"GCC_C_LANGUAGE_STANDARD = c99;" `nl`
-        				"GCC_WARN_ABOUT_RETURN_TYPE = YES;" `nl`
-        				"GCC_WARN_UNUSED_VARIABLE = YES;" `nl`
-        				"OTHER_LDFLAGS = \"-ObjC\";" `nl`
-        				"PREBINDING = NO;" `nl`
-        				"SDKROOT = iphoneos;" `nl`
-        			"};" `nl`
-        			"name = Release;" `nl`
-        		"};" `nl`
-        "/* End XCBuildConfiguration section */" `nl`
-        "" `nl`
-        "/* Begin XCConfigurationList section */" `nl`
-        		"1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget \"KitDeps\" */ = {" `nl`
-        			"isa = XCConfigurationList;" `nl`
-        			"buildConfigurations = (" `nl`
-        				"1DEB921F08733DC00010E9CD /* Debug */," `nl`
-        				"1DEB922008733DC00010E9CD /* Release */," `nl`
-        			");" `nl`
-        			"defaultConfigurationIsVisible = 0;" `nl`
-        			"defaultConfigurationName = Release;" `nl`
-        		"};" `nl`
-        		"1DEB922208733DC00010E9CD /* Build configuration list for PBXProject \"KitDepsCustom\" */ = {" `nl`
-        			"isa = XCConfigurationList;" `nl`
-        			"buildConfigurations = (" `nl`
-        				"1DEB922308733DC00010E9CD /* Debug */," `nl`
-        				"1DEB922408733DC00010E9CD /* Release */," `nl`
-        			");" `nl`
-        			"defaultConfigurationIsVisible = 0;" `nl`
-        			"defaultConfigurationName = Release;" `nl`
-        		"};" `nl`
-        "/* End XCConfigurationList section */" `nl`
-            
-        	"};" `nl`
-        	"rootObject = 0867D690FE84028FC02AAC07 /* Project object */;" `nl`
-        "}"
-
-  kitUpdateTarget = "/* Begin PBXLegacyTarget section */" `nl`
-        "470E2D641287730A0084AE6F /* KitUpdate */ = {" `nl`
-        "isa = PBXLegacyTarget;" `nl`
-        "buildArgumentsString = \"\";" `nl`
-        " buildConfigurationList = 470E2D721287731E0084AE6F /* Build configuration list for PBXLegacyTarget \"KitUpdate\" */;" `nl`
-        " buildPhases = (" `nl`
-        " );" `nl`
-        " buildToolPath = /usr/bin/make;" `nl`
-        " buildWorkingDirectory = \"\";" `nl`
-        " dependencies = (" `nl`
-        " );" `nl`
-        " name = KitUpdate;" `nl`
-        " passBuildSettingsInEnvironment = 1;" `nl`
-        " productName = KitUpdate;" `nl`
-        " };" `nl`
-        "470E2D721287731E0084AE6F /* Build configuration list for PBXLegacyTarget \"KitUpdate\" */ = {" `nl`
-      " isa = XCConfigurationList;" `nl`
-      " buildConfigurations = (" `nl`
-      " 470E2D651287730B0084AE6F /* Debug */," `nl`
-      " 470E2D661287730B0084AE6F /* Release */," `nl`
-      " );" `nl`
-      " defaultConfigurationIsVisible = 0;" `nl`
-      " defaultConfigurationName = Debug;" `nl`
-      "};" `nl`
-      "470E2D651287730B0084AE6F /* Debug */ = {" `nl`
-      " isa = XCBuildConfiguration;" `nl`
-      " buildSettings = {" `nl`
-      " COPY_PHASE_STRIP = NO;" `nl`
-      " GCC_DYNAMIC_NO_PIC = NO;" `nl`
-      " GCC_OPTIMIZATION_LEVEL = 0;" `nl`
-      " PRODUCT_NAME = KitUpdate;" `nl`
-      " };" `nl`
-      " name = Debug;" `nl`
-      "};" `nl`
-      "470E2D661287730B0084AE6F /* Release */ = {" `nl`
-      " isa = XCBuildConfiguration;" `nl`
-      " buildSettings = {" `nl`
-      " PRODUCT_NAME = KitUpdate;" `nl`
-      " };" `nl`
-      " name = Release;" `nl`
-      "};"
-  
-  main = do
-    putStrLn $ projectPbxProj "" "" "" "" ""
-
diff --git a/Kit/XCode/ProjectFileTemplate.hs b/Kit/XCode/ProjectFileTemplate.hs
new file mode 100644
--- /dev/null
+++ b/Kit/XCode/ProjectFileTemplate.hs
@@ -0,0 +1,202 @@
+{-
+
+  Constant sections of the project file
+-}
+module Kit.XCode.ProjectFileTemplate where
+
+  import Kit.XCode.Common
+  import Text.PList
+
+  import qualified Data.List as L
+
+  projectFile objects uuid = PListFile "!$*UTF8*$!" $ obj [
+        "archiveVersion" ~> val "1",
+        "classes" ~> obj [],
+        "objectVersion" ~> val "45",
+        "objects" ~> obj objects, 
+        "rootObject" ~> val uuid
+    ]
+
+  groupProductsUUID = "034768DFFF38A50411DB9C8B"
+  mainGroupUUID = "0867D691FE84028FC02AAC07"
+  classesGroupUUID = "08FB77AEFE84172EC02AAC07"
+  otherSourcesGroupUUID = "32C88DFF0371C24200C91783"
+  frameworksGroupUUID = "0867D69AFE84028FC02AAC07"
+
+  productRefUUID = "D2AAC07E0554694100DB518D"
+  kitConfigRefUUID = "4728C52F117C02B10027D7D1"
+
+  headersBuildPhaseUUID = "D2AAC07A0554694100DB518D"
+  sourcesBuildPhaseUUID = "D2AAC07B0554694100DB518D"
+  frameworksBuildPhaseUUID = "D2AAC07C0554694100DB518D"
+
+  makeProjectPList :: 
+    [PListObjectItem] -> -- build file section
+    [PListObjectItem] -> -- file refs section
+    PListObjectItem -> -- classes item
+    PListObjectItem -> -- headers section
+    PListObjectItem -> -- sources section
+    PListObjectItem -> -- frameworks section
+    PListObjectItem -> -- frameworks group
+    [FilePath] -> -- lib directories
+    PListFile 
+  makeProjectPList bfs fileRefsSection classes headers sources frameworks fg libDirs = projectFile objs "0867D690FE84028FC02AAC07" where
+      objs = bfs ++ fileRefsSection ++ [frameworks] ++ [fg] ++ next1 ++ [classes] ++ [next2] ++ [headers] ++ next3 ++ [sources] ++ buildConfigurations libDirs
+
+  next1 = [ groupProductsUUID ~> group "Products" [ val productRefUUID ],
+            mainGroupUUID ~> group "KitDeps" [
+              val classesGroupUUID,
+              val otherSourcesGroupUUID,
+              val frameworksGroupUUID,
+              val groupProductsUUID,
+              val kitConfigRefUUID
+            ]
+          ]
+    		
+  next2 = otherSourcesGroupUUID ~> group "Other Sources" [val "AA747D9E0F9514B9006C5449"]
+
+  next3 = ("D2AAC07D0554694100DB518D" ~> obj [
+        			"isa" ~> val "PBXNativeTarget",
+        			"buildConfigurationList" ~> val "1DEB921E08733DC00010E9CD",
+        			"buildPhases" ~> arr [ val headersBuildPhaseUUID, val sourcesBuildPhaseUUID, val frameworksBuildPhaseUUID ],
+              "buildRules" ~> arr [],
+        			"dependencies" ~> arr [],
+        			"name" ~> val "KitDeps",
+        			"productName" ~> val "KitDeps",
+        			"productReference" ~> val productRefUUID,
+        			"productType" ~> val "com.apple.product-type.library.static"
+        	  ]) : kitUpdateTarget ++ ["0867D690FE84028FC02AAC07" ~> obj [
+        			"isa" ~> val "PBXProject",
+        			"buildConfigurationList" ~> val "1DEB922208733DC00010E9CD",
+        			"compatibilityVersion" ~> val "Xcode 3.1",
+        			"hasScannedForEncodings" ~> val "1",
+        			"mainGroup" ~> val mainGroupUUID ,
+        			"productRefGroup" ~> val groupProductsUUID,
+        			"projectDirPath" ~> val "",
+        			"projectRoot" ~> val "",
+        			"targets" ~> arr [ val "D2AAC07D0554694100DB518D", val "470E2D641287730A0084AE6F" ] 
+        	]]
+
+  librarySearchPaths libDirs = "LIBRARY_SEARCH_PATHS" ~> val ("$(inherited) " ++ (L.intersperse " " libDirs >>= id))
+
+  buildConfigurations libDirs = let libSearch = librarySearchPaths libDirs in ["1DEB921F08733DC00010E9CD" ~> obj [
+        			"isa" ~> val "XCBuildConfiguration",
+        			"buildSettings" ~> obj [
+        				"ALWAYS_SEARCH_USER_PATHS" ~> val "NO",
+        				"ARCHS" ~> val "$(ARCHS_STANDARD_32_BIT)",
+        				"COPY_PHASE_STRIP" ~> val "NO",
+        				"DSTROOT" ~> val "/tmp/KitDeps.dst",
+        				"GCC_DYNAMIC_NO_PIC" ~> val "NO",
+        				"GCC_ENABLE_FIX_AND_CONTINUE" ~> val "YES",
+        				"GCC_MODEL_TUNING" ~> val "G5",
+        				"GCC_OPTIMIZATION_LEVEL" ~> val "0",
+        				"GCC_PRECOMPILE_PREFIX_HEADER" ~> val "YES",
+        				"GCC_PREFIX_HEADER" ~> val "KitDeps_Prefix.pch",
+        				"INSTALL_PATH" ~> val "/usr/local/lib",
+        				"PRODUCT_NAME" ~> val "KitDeps",
+                libSearch 
+              ],
+        			"name" ~> val "Debug"
+            ],
+        		"1DEB922008733DC00010E9CD" ~> obj [
+        			"isa" ~> val "XCBuildConfiguration",
+        			"buildSettings" ~> obj [
+        				"ALWAYS_SEARCH_USER_PATHS" ~> val "NO",
+        				"ARCHS" ~> val "$(ARCHS_STANDARD_32_BIT)",
+        				"DSTROOT" ~> val "/tmp/KitDeps.dst",
+        				"GCC_MODEL_TUNING" ~> val "G5",
+        				"GCC_PRECOMPILE_PREFIX_HEADER" ~> val "YES",
+        				"GCC_PREFIX_HEADER" ~> val "KitDeps_Prefix.pch",
+        				"INSTALL_PATH" ~> val "/usr/local/lib",
+        				"PRODUCT_NAME" ~> val "KitDeps",
+                libSearch
+                ],
+        			"name" ~> val "Release"
+              ],
+        		"1DEB922308733DC00010E9CD" ~> obj [
+        			"isa" ~> val "XCBuildConfiguration",
+        			"baseConfigurationReference" ~> val kitConfigRefUUID,
+        			"buildSettings" ~> obj [
+        				"ARCHS" ~> val "$(ARCHS_STANDARD_32_BIT)",
+        				"GCC_C_LANGUAGE_STANDARD" ~> val "c99",
+        				"GCC_OPTIMIZATION_LEVEL" ~> val "0",
+        				"GCC_WARN_ABOUT_RETURN_TYPE" ~> val "YES",
+        				"GCC_WARN_UNUSED_VARIABLE" ~> val "YES",
+        				"OTHER_LDFLAGS" ~> val "-ObjC",
+        				"PREBINDING" ~> val "NO",
+        				"SDKROOT" ~> val "iphoneos",
+                libSearch
+        			],
+        			"name" ~> val "Debug"
+        		],
+        		"1DEB922408733DC00010E9CD" ~> obj [
+        			"isa" ~> val "XCBuildConfiguration",
+        			"baseConfigurationReference" ~> val kitConfigRefUUID,
+        			"buildSettings" ~> obj [
+        				"ARCHS" ~> val "$(ARCHS_STANDARD_32_BIT)",
+        				"GCC_C_LANGUAGE_STANDARD" ~> val "c99",
+        				"GCC_WARN_ABOUT_RETURN_TYPE" ~> val "YES",
+        				"GCC_WARN_UNUSED_VARIABLE" ~> val "YES",
+        				"OTHER_LDFLAGS" ~> val "-ObjC",
+        				"PREBINDING" ~> val "NO",
+        				"SDKROOT" ~> val "iphoneos",
+                libSearch
+        			],
+        			"name" ~> val "Release"
+        		],
+        		"1DEB921E08733DC00010E9CD" ~> obj [
+        			"isa" ~> val "XCConfigurationList",
+        			"buildConfigurations" ~> arr [
+        				val "1DEB921F08733DC00010E9CD",
+        				val "1DEB922008733DC00010E9CD"
+        			],
+        			"defaultConfigurationIsVisible" ~> val "0",
+        			"defaultConfigurationName" ~> val "Release"
+        		],
+        		"1DEB922208733DC00010E9CD" ~> obj [
+        			"isa" ~> val "XCConfigurationList",
+        			"buildConfigurations" ~> arr [
+        				val "1DEB922308733DC00010E9CD",
+        				val "1DEB922408733DC00010E9CD"
+        			],
+        			"defaultConfigurationIsVisible" ~> val "0",
+        			"defaultConfigurationName" ~> val "Release"
+        		]
+        	]
+
+  kitUpdateTarget = [
+        "470E2D641287730A0084AE6F" ~> obj [ 
+          "isa" ~> val "PBXLegacyTarget",
+          "buildArgumentsString" ~> val "",
+          "buildConfigurationList" ~> val "470E2D721287731E0084AE6F",
+          "buildPhases" ~> arr [],
+          "buildToolPath" ~> val "/usr/bin/make",
+          "buildWorkingDirectory" ~> val "",
+          "dependencies" ~> arr [],
+          "name" ~> val "KitUpdate",
+          "passBuildSettingsInEnvironment" ~> val "1",
+          "productName" ~> val "KitUpdate"
+        ],
+        "470E2D721287731E0084AE6F" ~> obj [
+          "isa" ~> val "XCConfigurationList",
+          "buildConfigurations" ~> arr [ val "470E2D651287730B0084AE6F", val "470E2D661287730B0084AE6F" ],
+          "defaultConfigurationIsVisible" ~> val "0",
+          "defaultConfigurationName" ~> val "Debug"
+        ],
+        "470E2D651287730B0084AE6F" ~> obj [
+          "isa" ~> val "XCBuildConfiguration",
+          "buildSettings" ~> obj [
+            "COPY_PHASE_STRIP" ~> val "NO",
+            "GCC_DYNAMIC_NO_PIC" ~> val "NO",
+            "GCC_OPTIMIZATION_LEVEL" ~> val "0", 
+            "PRODUCT_NAME" ~> val "KitUpdate" 
+          ],
+          "name" ~> val "Debug"
+        ], 
+        "470E2D661287730B0084AE6F" ~> obj [
+          "isa" ~> val "XCBuildConfiguration",
+          "buildSettings" ~> obj [ "PRODUCT_NAME" ~> val "KitUpdate" ],
+          "name" ~> val "Release"
+        ]]
+  
+
diff --git a/Kit/XCode/XCConfig.hs b/Kit/XCode/XCConfig.hs
--- a/Kit/XCode/XCConfig.hs
+++ b/Kit/XCode/XCConfig.hs
@@ -6,8 +6,7 @@
   import Data.Maybe
   import Data.Either
   import Data.List
-  
-  import Data.String.Utils (strip)
+  import Data.Char (isSpace)
 
   type XCCSetting = (String, String)
   type XCCInclude = String
@@ -15,6 +14,9 @@
   data XCConfig = XCC { configName :: String, configSettings :: M.Map String String, configIncludes :: [XCCInclude] } deriving (Eq, Show)
   
   includeStart = "#include "
+  
+  strip :: String -> String
+  strip = f . f where f = reverse . dropWhile isSpace
   
   parseLine :: String -> Maybe (Either XCCSetting XCCInclude)
   parseLine l | includeStart `isPrefixOf` l = Just . Right . fromJust $ stripPrefix includeStart l
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -1,8 +1,3 @@
 module Main where
   import Kit.Main
-  import qualified Data.Map as M
-  import Kit.XCode.XCConfig
-  import Kit.XCode.OldPList
-  import Kit.XCode.PBXProject
-
   main = kitMain
diff --git a/Text/PList.hs b/Text/PList.hs
new file mode 100644
--- /dev/null
+++ b/Text/PList.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE TypeSynonymInstances #-}
+module Text.PList where
+
+import Data.List (isInfixOf, isPrefixOf, intersperse)
+
+-------------------------------------------------------------------------------
+-- | A Key/Value pair in a PList Object
+data PListObjectItem = PListObjectItem {
+    itemKey :: String, -- The key in the object
+    itemValue :: PListType -- The value in the object
+  } deriving Eq 
+
+data PListType = PListValue String
+               | PListArray [PListType]
+               | PListObject [PListObjectItem]
+               deriving Eq
+
+val x = PListValue x 
+arr = PListArray
+obj = PListObject
+
+infixl 1 ~> 
+a ~> b = PListObjectItem a b
+
+quote s = "\"" ++ s ++ "\""
+quotable "" = True
+quotable s = or $ map (\x -> x `isInfixOf` s && (not $ "sourcecode" `isPrefixOf` s)) quote_triggers
+              where quote_triggers = ["-", "<", ">", " ", ".m", ".h", "_", "$"]
+
+instance Show PListObjectItem where
+  show (PListObjectItem k v) = k ++ " = " ++ show v ++ ";\n"
+
+instance Show PListType where
+  show (PListValue a) = (if (quotable a) then quote a else a) 
+  show (PListArray xs) = "(" ++ ((intersperse ", " $ map show xs) >>= id) ++ ")"
+  show (PListObject kvs) = "{\n" ++ (kvs >>= (\x -> "  " ++ show x)) ++ "}\n"
+
+data PListFile = PListFile { pListFileCharset :: String, pListFileValue :: PListType }
+
+instance Show PListFile where
+  show (PListFile charset value) = "// " ++ charset ++ "\n" ++ show value ++ "\n"
+
diff --git a/kit.cabal b/kit.cabal
--- a/kit.cabal
+++ b/kit.cabal
@@ -1,5 +1,5 @@
 name:           kit
-version:        0.4.4
+version:        0.5
 cabal-version:  >=1.2
 build-type:     Simple
 license:        BSD3
@@ -16,11 +16,9 @@
   buildable:      True
   build-depends:  process -any, network -any, mtl -any, json -any,
                   filepath -any, directory -any, containers -any, cmdargs >=0.3,
-                  bytestring -any, base >=3 && <5, QuickCheck -any, MissingH -any,
+                  bytestring -any, base >=3 && <5, QuickCheck -any,
                   HTTP >=4000.0.9, Glob >= 0.5
 
   hs-source-dirs: .
-  other-modules:  Kit.Model Kit.Main Kit.Package
-                  Kit.Project Kit.Repository Kit.Util Kit.XCode.Builder
-                  Kit.XCode.Common Kit.XCode.OldPList Kit.XCode.PBXProject
-                  Kit.XCode.ProjectFile Kit.XCode.XCConfig
+  other-modules:  Kit.Model Kit.Main Kit.Package Kit.Project Kit.Repository Kit.Util Kit.XCode.Builder
+                  Kit.XCode.Common Kit.XCode.ProjectFileTemplate Kit.XCode.XCConfig Text.PList
