diff --git a/Distribution/MacOSX.hs b/Distribution/MacOSX.hs
--- a/Distribution/MacOSX.hs
+++ b/Distribution/MacOSX.hs
@@ -1,21 +1,25 @@
-{- | Cabal support for creating Mac OSX application bundles.
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE CPP #-}
+  {- | Cabal support for creating Mac OSX application bundles.
 
-GUI applications on Mac OSX should be run as application /bundles/;
-these wrap an executable in a particular directory structure which can
-also carry resources such as icons, program metadata, images, other
-binaries, and copies of shared libraries.
+  GUI applications on Mac OSX should be run as application /bundles/;
+  these wrap an executable in a particular directory structure which can
+  also carry resources such as icons, program metadata, images, other
+  binaries, and copies of shared libraries.
 
-This module provides a Cabal post-build hook for creating such
-application bundles, and controlling their contents.
+  This module provides a Cabal post-build hook for creating such
+  application bundles, and controlling their contents.
 
-For more information about OSX application bundles, look for the
-/Bundle Programming Guide/ on the /Apple Developer Connection/
-website, <http://developer.apple.com/>.
+  For more information about OSX application bundles, look for the
+  /Bundle Programming Guide/ on the /Apple Developer Connection/
+  website, <http://developer.apple.com/>.
 
--}
+  -}
 
 module Distribution.MacOSX (
-  appBundleBuildHook, appBundleInstallHook,
+  appBundleBuildHook,
+  appBundleInstallHook,
+  appBundleCopyHook,
   makeAppBundle,
   MacApp(..),
   ChaseDeps(..),
@@ -23,27 +27,34 @@
   defaultExclusions
 ) where
 
+import Control.Exception
+import Prelude hiding ( catch )
 import Control.Monad (forM_, when)
-import Data.String.Utils (replace)
-import Distribution.PackageDescription (PackageDescription(..),
-                                        Executable(..))
+import Data.List ( isPrefixOf )
+import System.Cmd (system)
+import System.FilePath
+import System.Directory (copyFile, createDirectoryIfMissing, getHomeDirectory)
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+
+import Distribution.PackageDescription (PackageDescription(..))
 import Distribution.Simple
 import Distribution.Simple.InstallDirs (bindir, prefix, CopyDest(NoCopyDest))
 import Distribution.Simple.LocalBuildInfo (absoluteInstallDirs, LocalBuildInfo(..))
-import Distribution.Simple.Setup (BuildFlags, InstallFlags,
-                                  fromFlagOrDefault, installVerbosity
-                                 )
+import Distribution.Simple.Setup (BuildFlags, InstallFlags, CopyFlags, fromFlagOrDefault, installVerbosity, copyVerbosity)
 import Distribution.Simple.Utils (installDirectoryContents, installExecutableFile)
-import Distribution.Verbosity (normal)
-import System.Cmd (system)
-import System.FilePath
+#if MIN_VERSION_Cabal(1,18,0)
+import Distribution.System (Platform (..), OS (OSX))
+#else
 import System.Info (os)
-import System.Directory (copyFile, createDirectoryIfMissing)
-import System.Exit
+#endif
+import Distribution.Verbosity (normal, Verbosity)
 
+import Distribution.MacOSX.Internal
 import Distribution.MacOSX.AppBuildInfo
 import Distribution.MacOSX.Common
 import Distribution.MacOSX.Dependencies
+import Distribution.MacOSX.Templates
 
 -- | Post-build hook for OS X application bundles.  Does nothing if
 -- called on another O/S.
@@ -55,13 +66,15 @@
           -- 'Distribution.Simple.postBuild'.
   -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
 appBundleBuildHook apps _ _ pkg localb =
+#if MIN_VERSION_Cabal(1,18,0)
+  if isMacOS localb
+#else
   if isMacOS
-     then forM_ apps' $ makeAppBundle . toAppBuildInfo localb
+#endif
+     then do let buildDirLbi = buildDir localb
+             let macApps = getMacAppsForBuildableExecutors apps (executables pkg)
+             forM_ macApps (makeAppBundle . createAppBuildInfo buildDirLbi)
      else putStrLn "Not OS X, so not building an application bundle."
-  where apps' = case apps of
-                      [] -> map mkDefault $ executables pkg
-                      xs -> xs
-        mkDefault x = MacApp (exeName x) Nothing Nothing [] [] DoNotChase
 
 -- | Post-install hook for OS X application bundles.  Copies the
 -- application bundle (assuming you are also using the appBundleBuildHook)
@@ -74,42 +87,129 @@
   -> Args -- ^ All other parameters as per
           -- 'Distribution.Simple.postInstall'.
   -> InstallFlags -> PackageDescription -> LocalBuildInfo -> IO ()
-appBundleInstallHook apps _ iflags pkg localb = when isMacOS $ do
-  let verbosity = fromFlagOrDefault normal (installVerbosity iflags)
+appBundleInstallHook apps _ iflags =
+	appBundleInstallOrCopyHook apps
+	    (fromFlagOrDefault normal (installVerbosity iflags))
+{-# DEPRECATED appBundleInstallHook "Use appBundleCopyHook instead" #-}
+
+-- | Post-copy hook for OS X application bundles.  Copies the
+-- application bundle (assuming you are also using the appBundleBuildHook)
+-- to @$prefix/Applications@
+-- Does nothing if called on another O/S.
+-- Use this instead of appBundleInstallHook (do not hook
+-- both postInst and postCopy).
+appBundleCopyHook ::
+  [MacApp] -- ^ List of applications to build; if empty, an
+           -- application is built for each executable in the package,
+           -- with no icon or plist, and no dependency-chasing.
+  -> Args -- ^ All other parameters as per
+          -- 'Distribution.Simple.postCopy'.
+  -> CopyFlags -> PackageDescription -> LocalBuildInfo -> IO ()
+appBundleCopyHook apps _ cflags =
+	appBundleInstallOrCopyHook apps
+	    (fromFlagOrDefault normal (copyVerbosity cflags))
+
+appBundleInstallOrCopyHook ::
+  [MacApp] -- ^ List of applications to build; if empty, an
+           -- application is built for each executable in the package,
+           -- with no icon or plist, and no dependency-chasing.
+  -> Verbosity
+  -> PackageDescription -> LocalBuildInfo -> IO ()
+#if MIN_VERSION_Cabal(1,18,0)
+appBundleInstallOrCopyHook apps verbosity pkg localb = when (isMacOS localb) $ do
+#else
+appBundleInstallOrCopyHook apps verbosity pkg localb = when isMacOS $ do
+#endif
+  libraryHaskell  <- flip fmap getHomeDirectory $ (</> "Library/Haskell")
+  let standardPrefix = (libraryHaskell ++ "/") `isPrefixOf` prefix installDir
+  let applicationsDir = if standardPrefix
+                           then libraryHaskell    </> "Applications"
+                           else prefix installDir </> "Applications"
   createDirectoryIfMissing False applicationsDir
   forM_ apps $ \app -> do
     let appInfo    = toAppBuildInfo localb app
-        appPathSrc = appPath appInfo
+        appPathSrc = abAppPath appInfo
         appPathTgt = applicationsDir </> takeFileName appPathSrc
         exe ap = ap </> pathInApp app (appName app)
     installDirectoryContents verbosity appPathSrc appPathTgt
     installExecutableFile    verbosity (exe appPathSrc) (exe appPathTgt)
     -- generate a tiny shell script for users who expect to run their
     -- applications from the command line with flags and all
-    let script = "`dirname $0`" </> "../Applications"
-                                </> takeFileName appPathSrc
-                                </> "Contents/MacOS" </> appName app
-                 ++ " \"$@\""
+    let script = if standardPrefix
+                    then bundleScriptLibraryHaskell localb app
+                    else bundleScriptElsewhere      localb app
         scriptFileSrc = buildDir localb   </> "_" ++ appName app <.> "sh"
         scriptFileTgt = bindir installDir </> appName app
     writeFile scriptFileSrc script
     installExecutableFile verbosity scriptFileSrc scriptFileTgt
   where
     installDir = absoluteInstallDirs pkg localb NoCopyDest
-    applicationsDir = prefix installDir </> "Applications"
 
+bundleScriptLibraryHaskell :: LocalBuildInfo -> MacApp -> String
+bundleScriptLibraryHaskell localb app = unlines
+  [ "#!/bin/bash"
+  , "$HOME/Library/Haskell/Applications"
+           </> takeFileName appPathSrc
+           </> "Contents/MacOS" </> appName app ++ " \"$@\""
+  ]
+  where
+    appInfo    = toAppBuildInfo localb app
+    appPathSrc = abAppPath appInfo
+ 
+bundleScriptElsewhere :: LocalBuildInfo -> MacApp -> String
+bundleScriptElsewhere localb app = unlines
+  [ "#!/bin/bash"
+  , "MAX_DEPTH=256"
+  , "COUNTER=0"
+  , "ZERO=$0"
+  , "STATUS=0"
+  , ""
+  , "# The counter is just a safeguard in case I'd done something silly"
+  , "while [ $STATUS -eq 0 -a $COUNTER -lt $MAX_DEPTH ]; do"
+  , "  COUNTER=$(($COUNTER+1))"
+  , "  NZERO=`readlink $ZERO`; STATUS=$?"
+  , "  if [ $STATUS -eq 0 ]; then"
+  , "      # go to my parent dir"
+  , "      pushd $(dirname $ZERO)  > /dev/null"
+  , "      # now follow the symlink if at all"
+  , "      pushd $(dirname $NZERO) > /dev/null"
+  , "      ZERO=$PWD/$(basename $NZERO)"
+  , "      popd > /dev/null"
+  , "      popd > /dev/null"
+  , "  fi"
+  , "done"
+  , "if [ $COUNTER -ge $MAX_DEPTH ]; then"
+  , "  echo >&2 Urk! exceeded symlink depth of $MAX_DEPTH trying to dereference $0"
+  , "  exit 1"
+  , "fi"
+  , "`dirname $ZERO`" </> "../Applications"
+           </> takeFileName appPathSrc
+           </> "Contents/MacOS" </> appName app ++ " \"$@\""
+  ]
+  where
+    appInfo    = toAppBuildInfo localb app
+    appPathSrc = abAppPath appInfo
+
+#if MIN_VERSION_Cabal(1,18,0)
+isMacOS :: LocalBuildInfo -> Bool
+isMacOS localb = case hostPlatform localb of
+  Platform _ OSX -> True
+  _ -> False
+#else
 isMacOS :: Bool
 isMacOS = os == "darwin"
+#endif
 
+
 -- | Given a 'MacApp' in context, make an application bundle in the
 -- build area. (for internal use only)
 makeAppBundle :: AppBuildInfo -> IO ()
 makeAppBundle appInfo@(AppBuildInfo appPath _ app) =
-  do createAppDir appInfo
+  do _ <- createAppDir appInfo
      maybeCopyPlist appPath app
      maybeCopyIcon appPath app
-       `catch` \err -> putStrLn ("Warning: could not set up icon for " ++
-                                 appName app ++ ": " ++ show err)
+       `catch` \(SomeException err) ->
+          putStrLn $ "Warning: could not set up icon for " ++ appName app ++ ": " ++ show err
      includeResources appPath app
      includeDependencies appPath app
      osxIncantations appPath app
@@ -123,7 +223,7 @@
      createDirectoryIfMissing False appPath
      createDirectoryIfMissing True  $ takeDirectory exeDest
      createDirectoryIfMissing True  $ appPath </> "Contents/Resources"
-     putStrLn $ "Copying executable " ++ appName app ++ " into place"
+     putStrLn $ "Copying executable " ++ appName app ++ " into place from " ++ exeSrc ++ " to " ++ exeDest
      copyFile exeSrc exeDest
      return appPath
   where exeDest = appPath </> pathInApp app (appName app)
@@ -155,9 +255,9 @@
     Nothing -> case appIcon app of
                  Just icPath ->
                    do -- Need a plist to support icon; use default.
-                     let pl = replace "$program" (appName app) plistTemplate
-                         pl' = replace "$iconPath" (takeFileName icPath) pl
-                     writeFile plDest pl'
+                     let pl  = T.replace "$program"  (T.pack (appName app)) plistTemplate
+                         pl' = T.replace "$iconPath" (T.pack (takeFileName icPath)) pl
+                     T.writeFile plDest pl'
                      return ()
                  Nothing -> return () -- No icon, no plist, nothing to do.
     where plDest = appPath </> "Contents/Info.plist"
@@ -173,62 +273,3 @@
          copyFile icPath $
                   appPath </> "Contents/Resources" </> takeFileName icPath
     Nothing -> return ()
-
--- | Perform various magical OS X incantations for turning the app
--- directory into a bundle proper.
-osxIncantations ::
-  FilePath -- ^ Path to application bundle root.
-  -> MacApp -> IO ()
-osxIncantations appPath app =
-  do putStrLn "Running Rez, etc."
-     ExitSuccess <- system $ rez ++ " Carbon.r -o " ++
-       appPath </> pathInApp app (appName app)
-     writeFile (appPath </> "PkgInfo") "APPL????"
-     -- Tell Finder about the icon.
-     ExitSuccess <- system $ setFile ++ " -a C " ++ appPath </> "Contents"
-     return ()
-
--- | Path to @Rez@ tool.
-rez :: FilePath
-rez = "/Developer/Tools/Rez"
-
--- | Path to @SetFile@ tool.
-setFile :: FilePath
-setFile = "/Developer/Tools/SetFile"
-
--- | Default plist template, based on that in macosx-app from wx (but
--- with version stuff removed).
-plistTemplate :: String
-plistTemplate = "\
-    \<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
-    \<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">\n\
-    \<plist version=\"0.9\">\n\
-    \<dict>\n\
-            \<key>CFBundleInfoDictionaryVersion</key>\n\
-            \<string>6.0</string>\n\
-            \<key>CFBundleIdentifier</key>\n\
-            \<string>org.haskell.$program</string>\n\
-            \<key>CFBundleDevelopmentRegion</key>\n\
-            \<string>English</string>\n\
-            \<key>CFBundleExecutable</key>\n\
-            \<string>$program</string>\n\
-            \<key>CFBundleIconFile</key>\n\
-            \<string>$iconPath</string>\n\
-            \<key>CFBundleName</key>\n\
-            \<string>$program</string>\n\
-            \<key>CFBundlePackageType</key>\n\
-            \<string>APPL</string>\n\
-            \<key>CFBundleSignature</key>\n\
-            \<string>????</string>\n\
-            \<key>CFBundleVersion</key>\n\
-            \<string>1.0</string>\n\
-            \<key>CFBundleShortVersionString</key>\n\
-            \<string>1.0</string>\n\
-            \<key>CFBundleGetInfoString</key>\n\
-            \<string>$program, bundled by cabal-macosx</string>\n\
-            \<key>LSRequiresCarbon</key>\n\
-            \<true/>\n\
-            \<key>CSResourcesFileMapped</key>\n\
-            \<true/>\n\
-    \</dict>\n\
-    \</plist>"
diff --git a/Distribution/MacOSX/AppBuildInfo.hs b/Distribution/MacOSX/AppBuildInfo.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/MacOSX/AppBuildInfo.hs
@@ -0,0 +1,35 @@
+-- | Information used to help create an application bundle
+module Distribution.MacOSX.AppBuildInfo where
+
+import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
+import System.FilePath
+
+import Distribution.MacOSX.Common
+
+-- | Information needed to build a bundle
+--
+--   This exists to make it possible to have a standalone
+--   macosx-app executable without it necessarily having to
+--   know a lot of Cabal internals
+data AppBuildInfo = AppBuildInfo
+  { -- | Location of the application bundle being built
+    abAppPath    :: FilePath
+    -- | Location of the original executable that was built
+  , abAppOrigExe :: FilePath
+    -- |
+  , abApp        :: MacApp
+  }
+
+-- | @toAppBuildInfo l m@ returns information for an application bundle
+--   within the @l@ build directory
+toAppBuildInfo :: LocalBuildInfo -> MacApp -> AppBuildInfo
+toAppBuildInfo localb app = createAppBuildInfo (buildDir localb) app
+
+-- | @createAppBuildInfo d m@ returns information for an application bundle
+--   within the @d@ build directory from LocalBuildInfo
+createAppBuildInfo :: FilePath -> MacApp -> AppBuildInfo
+createAppBuildInfo buildDirLocalBuildInfo app = AppBuildInfo
+  { abAppPath    = buildDirLocalBuildInfo </> appName app <.> "app"
+  , abAppOrigExe = buildDirLocalBuildInfo </> appName app </> appName app
+  , abApp        = app
+  }
diff --git a/Distribution/MacOSX/Common.hs b/Distribution/MacOSX/Common.hs
--- a/Distribution/MacOSX/Common.hs
+++ b/Distribution/MacOSX/Common.hs
@@ -1,3 +1,4 @@
+-- | Utility functions
 module Distribution.MacOSX.Common where
 
 import Data.List
diff --git a/Distribution/MacOSX/DG.hs b/Distribution/MacOSX/DG.hs
--- a/Distribution/MacOSX/DG.hs
+++ b/Distribution/MacOSX/DG.hs
diff --git a/Distribution/MacOSX/Dependencies.hs b/Distribution/MacOSX/Dependencies.hs
--- a/Distribution/MacOSX/Dependencies.hs
+++ b/Distribution/MacOSX/Dependencies.hs
@@ -142,7 +142,9 @@
   -> Exclusions -- ^ List of exclusions for dependency chasing.
   -> IO FDeps
 getFDeps appPath app path exclusions =
-  do contents <- readProcess oTool ["-L", absPath] ""
+  do putStrLn $ "path: " ++ path
+     contents <- readProcess oTool ["-L", absPath] ""
+     putStrLn $ "contents: " ++ contents
      case parse parseFileDeps "" contents of
        Left err -> error $ show err
        Right fDeps -> return $ exclude exclusions fDeps
@@ -152,6 +154,7 @@
         parseFileDeps :: Parser FDeps
         parseFileDeps = do f <- manyTill (noneOf ":") (char ':')
                            _ <- char '\n'
+
                            deps <- parseDepOrName `sepEndBy` char '\n'
                            eof
                            return $ FDeps f $ filter (f /=) $ catMaybes deps
@@ -159,12 +162,22 @@
         parseDepOrName = do c <- oneOf "\t/"
                             case c of
                               '\t' -> -- A dependency.
-                                      do dep <- parseDep
-                                         return $ Just dep
+                                      do dep <- parseDepOrIgnoreAt
+                                         return $ dep
                               '/' -> -- Same filename, alternative arch
                                      do _ <- manyTill (noneOf ":") (char ':')
                                         return Nothing
                               _ -> error "Can't happen"
+        parseDepOrIgnoreAt :: Parser (Maybe FilePath)
+        parseDepOrIgnoreAt = do c <- lookAhead (oneOf "/@")
+                                case c of
+                                  '/' -> -- A dependency.
+                                         do dep <- parseDep
+                                            return $ Just $ dep
+                                  '@' -> -- ignore entries that start with @
+                                         do _ <- manyTill (noneOf ")") (char ')')
+                                            return Nothing
+                                  _ -> error "Can't happen"
         parseDep :: Parser FilePath
         parseDep = do dep <- manyTill (noneOf " ") (char ' ')
                       _ <- char '('
@@ -213,10 +226,17 @@
 updateDependency appPath app src tgt =
   do putStrLn $ "Updating " ++ newLib ++ "'s dependency on " ++ tgt ++
                    " to " ++ tgt'
+     -- Ensure we have write permissions while editing the library. Notably,
+     -- Homebrew removes write permissions from installed files.
+     perm <- getPermissions newLib
+     setPermissions newLib perm { writable = True }
      let cmd = iTool ++ " -change " ++ show tgt ++ " " ++ show tgt' ++
                    " " ++ show newLib
-     --putStrLn cmd
-     ExitSuccess <- system cmd
+     exitCode <- system cmd
+     setPermissions newLib perm
+     when (exitCode /= ExitSuccess) $
+       error $ "Failed to update library dependencies on " ++ show newLib ++
+        " with command: " ++ cmd
      return ()
   where tgt' = "@executable_path/../Frameworks/" </> makeRelative "/" tgt
         newLib = appPath </> pathInApp app src
diff --git a/Distribution/MacOSX/Internal.hs b/Distribution/MacOSX/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/MacOSX/Internal.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE CPP #-}
+{- | Cabal support for creating Mac OSX application bundles.
+
+GUI applications on Mac OSX should be run as application /bundles/;
+these wrap an executable in a particular directory structure which can
+also carry resources such as icons, program metadata, images, other
+binaries, and copies of shared libraries.
+
+This module provides internals to a Cabal post-build hook for creating such
+application bundles, and controlling their contents.
+
+For more information about OSX application bundles, look for the
+/Bundle Programming Guide/ on the /Apple Developer Connection/
+website, <http://developer.apple.com/>.
+
+-}
+
+module Distribution.MacOSX.Internal (
+  getMacAppsForBuildableExecutors,
+  osxIncantations
+) where
+
+#if MIN_VERSION_Cabal(2,0,0)
+import Data.String (fromString)
+import Distribution.Text (display)
+import Distribution.Types.UnqualComponentName (unUnqualComponentName)
+#endif
+import Prelude hiding ( catch )
+import System.Cmd ( system )
+import System.Exit
+import System.FilePath
+import Control.Monad (filterM)
+import System.Directory (doesDirectoryExist)
+
+import Distribution.PackageDescription (BuildInfo(..), Executable(..))
+import Distribution.MacOSX.Common
+
+-- | Filter or create new 'MacApp's that are associated by name to buildable 'Executable's.
+getMacAppsForBuildableExecutors ::
+  [MacApp] -- ^ List of 'MacApp's to filter if any.
+  -> [Executable] -- ^ List of 'Executable's from .cabal.
+  -> [MacApp] -- ^ Returned list of 'MacApp's that are associated by name to buildable 'Executable's.
+getMacAppsForBuildableExecutors macApps executables =
+  case macApps of
+    [] -> map mkDefault buildables
+    xs -> filter buildableApp xs
+  where -- Make a default MacApp in absence of explicit from Setup.hs
+#if MIN_VERSION_Cabal(2,0,0)
+        mkDefault x = MacApp (unUnqualComponentName $ exeName x) Nothing Nothing [] [] DoNotChase
+#else
+        mkDefault x = MacApp (exeName x) Nothing Nothing [] [] DoNotChase
+#endif
+
+        -- Check if a MacApp is in that list of buildable executables.
+        buildableApp :: MacApp -> Bool
+#if MIN_VERSION_Cabal(2,0,0)
+        buildableApp app = any (\e -> exeName e == fromString (appName app)) buildables
+#else
+        buildableApp app = any (\e -> exeName e == appName app) buildables
+#endif
+
+        -- List of buildable executables from .cabal file.
+        buildables :: [Executable]
+        buildables = filter (buildable . buildInfo) executables
+
+-- | Perform various magical OS X incantations for turning the app
+-- directory into a bundle proper.
+osxIncantations ::
+  FilePath -- ^ Path to application bundle root.
+  -> MacApp -> IO ()
+osxIncantations appPath app =
+  do writeFile (appPath </> "PkgInfo") "APPL????"
+     return ()
diff --git a/Distribution/MacOSX/Templates.hs b/Distribution/MacOSX/Templates.hs
new file mode 100644
--- /dev/null
+++ b/Distribution/MacOSX/Templates.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+-- | Templates for the bundle.
+
+module Distribution.MacOSX.Templates (
+  plistTemplate
+) where
+
+import Data.Text ( Text )
+
+-- | Default plist template, based on that in macosx-app from wx (but
+-- with version stuff removed).
+plistTemplate :: Text
+plistTemplate = "\
+    \<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+    \<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">\n\
+    \<plist version=\"0.9\">\n\
+    \<dict>\n\
+            \<key>CFBundleInfoDictionaryVersion</key>\n\
+            \<string>6.0</string>\n\
+            \<key>CFBundleIdentifier</key>\n\
+            \<string>org.haskell.$program</string>\n\
+            \<key>CFBundleDevelopmentRegion</key>\n\
+            \<string>English</string>\n\
+            \<key>CFBundleExecutable</key>\n\
+            \<string>$program</string>\n\
+            \<key>CFBundleIconFile</key>\n\
+            \<string>$iconPath</string>\n\
+            \<key>CFBundleName</key>\n\
+            \<string>$program</string>\n\
+            \<key>CFBundlePackageType</key>\n\
+            \<string>APPL</string>\n\
+            \<key>CFBundleSignature</key>\n\
+            \<string>????</string>\n\
+            \<key>CFBundleVersion</key>\n\
+            \<string>1.0</string>\n\
+            \<key>CFBundleShortVersionString</key>\n\
+            \<string>1.0</string>\n\
+            \<key>CFBundleGetInfoString</key>\n\
+            \<string>$program, bundled by cabal-macosx</string>\n\
+            \<key>LSRequiresCarbon</key>\n\
+            \<true/>\n\
+            \<key>CSResourcesFileMapped</key>\n\
+            \<true/>\n\
+    \</dict>\n\
+    \</plist>"
diff --git a/cabal-macosx.cabal b/cabal-macosx.cabal
--- a/cabal-macosx.cabal
+++ b/cabal-macosx.cabal
@@ -1,5 +1,5 @@
 Name:                   cabal-macosx
-Version:                0.1.2.2
+Version:                0.2.4.2
 Stability:              Alpha
 Synopsis:               Cabal support for creating Mac OSX application bundles.
 Description:
@@ -21,27 +21,63 @@
 License-file:           LICENSE
 Copyright:              Eric Kow & Andy Gimblett
 Author:                 Eric Kow <eric.kow@gmail.com> & Andy Gimblett <haskell@gimbo.org.uk>
-Maintainer:             Andy Gimblett <haskell@gimbo.org.uk>
-Homepage:               http://github.com/gimbo/cabal-macosx
+Maintainer:             Daniele Francesconi <dfrancesconi12@gmail.com>
+Homepage:               http://github.com/danfran/cabal-macosx
 Build-Type:             Simple
-Cabal-Version:          >=1.6
+Cabal-Version:          >=1.8
+Tested-With:            GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.1, GHC == 7.10.2, GHC == 7.10.3, GHC == 8.0.1, GHC == 8.0.2
 
 Source-Repository head
     Type:         git
-    Location:     http://github.com/gimbo/cabal-macosx
+    Location:     http://github.com/danfran/cabal-macosx
 
 Library
-  Build-Depends:   base >= 4 && < 5, Cabal >= 1.6, directory
-               ,   fgl >= 5.4.2.2 && < 5.5
-               ,   filepath, MissingH, parsec, process
-  Exposed-modules: Distribution.MacOSX
-  Other-modules:   Distribution.MacOSX.Common,
-                   Distribution.MacOSX.Dependencies,
-                   Distribution.MacOSX.DG
-  ghc-options:     -fwarn-tabs -Wall
+  Build-Depends:    base == 4.*
+                    , Cabal >= 1.6, directory
+                    , hscolour
+                    , fgl
+                    , filepath
+                    , parsec
+                    , process
+                    , text
+                    , containers
+  Exposed-modules:  Distribution.MacOSX
+  Other-modules:    Distribution.MacOSX.Internal,
+                    Distribution.MacOSX.Common,
+                    Distribution.MacOSX.AppBuildInfo,
+                    Distribution.MacOSX.Dependencies,
+                    Distribution.MacOSX.DG,
+                    Distribution.MacOSX.Templates
+  ghc-options:      -fwarn-tabs -Wall
 
 Executable macosx-app
-  Main-is:         macosx-app.hs
-  Build-Depends:   base >= 4 && < 5, Cabal >= 1.6, directory
-               ,   fgl >= 5.4.2.2 && < 5.5
-               ,   filepath, MissingH, parsec, process
+  Main-is:          macosx-app.hs
+  Build-Depends:    base == 4.*
+                    , Cabal >= 1.6
+                    , directory
+                    , fgl
+                    , filepath
+                    , parsec
+                    , process
+                    , text
+                    , containers
+
+test-suite tests
+  ghc-options:      -Wall
+  hs-source-dirs:   .,tests
+  Main-is:          Main.hs
+  Type:             exitcode-stdio-1.0
+  Other-modules:    Distribution.MacOSX.Internal.Tests,
+                    Distribution.MacOSX.Common,
+                    Distribution.MacOSX.Internal
+  Build-depends:    base == 4.*
+                    , HUnit
+                    , test-framework
+                    , test-framework-hunit
+                    , temporary
+                    , Cabal >= 1.6
+                    , filepath
+                    , process
+                    , text
+                    , containers
+                    , directory
diff --git a/macosx-app.hs b/macosx-app.hs
--- a/macosx-app.hs
+++ b/macosx-app.hs
@@ -20,9 +20,9 @@
                        , otherBins = []
                        , appDeps   = DoNotChase
                        } 
-      appInfo = AppBuildInfo { app        = macapp
-                             , appPath    = appName macapp <.> "app"
-                             , appOrigExe = exe
+      appInfo = AppBuildInfo { abApp        = macapp
+                             , abAppPath    = appName macapp <.> "app"
+                             , abAppOrigExe = exe
                              }
   if exeExists
      then makeAppBundle appInfo
diff --git a/tests/Distribution/MacOSX/Internal/Tests.hs b/tests/Distribution/MacOSX/Internal/Tests.hs
new file mode 100644
--- /dev/null
+++ b/tests/Distribution/MacOSX/Internal/Tests.hs
@@ -0,0 +1,88 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE CPP #-}
+module Distribution.MacOSX.Internal.Tests where
+
+import Prelude hiding (catch)
+import Test.HUnit (Assertion, assertEqual)
+import Test.Framework (Test, mutuallyExclusive, testGroup)
+import Test.Framework.Providers.HUnit (testCase)
+
+#if MIN_VERSION_Cabal(2,0,0)
+import Distribution.Types.ExecutableScope
+#endif
+import Distribution.PackageDescription (BuildInfo(..), Executable(..), emptyBuildInfo, emptyExecutable)
+
+import Distribution.MacOSX.Internal (getMacAppsForBuildableExecutors)
+import Distribution.MacOSX.Common
+
+#if MIN_VERSION_Cabal(2,0,0)
+getExecutableScopeUnknown :: ExecutableScope
+getExecutableScopeUnknown = exeScope $ emptyExecutable
+#endif
+
+macosxInternalTests :: Test
+macosxInternalTests = testGroup "Distribution.MacOSX.Internal"
+    [ mutuallyExclusive $ testGroup "MacOSX Internal"
+        [ -- I should consider to use QuickCheck maybe... :)
+          testCase "given nothing then should not try to build any mac-app" testBuildMacApp_noInput,
+          testCase "given no executables then should not try to build any mac-app" testBuildMacApp_noExecutables,
+          testCase "given only two executables then should try to build two mac-apps" testBuildMacApp_twoBuildableExecutables,
+          testCase "given only two executables and one not executable then should try to build one mac-app" testBuildMacApp_twoExcetuablesOneBuildableAndOneNot,
+          testCase "given two executables and one not executable and two apps then should try to build one mac-app" testBuildMacApp_twoAppsAndTwoExecutablesOneBuildableOneNot
+        ]
+    ]
+
+testBuildMacApp_noInput :: Assertion
+testBuildMacApp_noInput = do
+    let actual = getMacAppsForBuildableExecutors [] []
+    let expected = []
+    assertEqual "nothing should be built" expected actual
+
+testBuildMacApp_noExecutables :: Assertion
+testBuildMacApp_noExecutables = do
+    let apps = [MacApp "Dummy App" Nothing Nothing [] [] DoNotChase]
+    let actual = getMacAppsForBuildableExecutors apps []
+    let expected = []
+    assertEqual "nothing should be built" expected actual
+
+testBuildMacApp_twoBuildableExecutables :: Assertion
+testBuildMacApp_twoBuildableExecutables = do
+#if MIN_VERSION_Cabal(2,0,0)
+    let execs = [ Executable "Dummy One" "/tmp" getExecutableScopeUnknown emptyBuildInfo
+                  , Executable "Dummy Two" "/tmp" getExecutableScopeUnknown emptyBuildInfo ]
+#else
+    let execs = [ Executable "Dummy One" "/tmp" emptyBuildInfo
+                  , Executable "Dummy Two" "/tmp" emptyBuildInfo ]
+#endif
+    let actual = getMacAppsForBuildableExecutors [] execs
+    let expected = [ MacApp "Dummy One" Nothing Nothing [] [] DoNotChase
+                     , MacApp "Dummy Two" Nothing Nothing [] [] DoNotChase ]
+    assertEqual "two mac-apps should be built" expected actual
+
+testBuildMacApp_twoExcetuablesOneBuildableAndOneNot :: Assertion
+testBuildMacApp_twoExcetuablesOneBuildableAndOneNot = do
+#if MIN_VERSION_Cabal(2,0,0)
+    let execs = [ Executable "Dummy One" "/tmp" getExecutableScopeUnknown (emptyBuildInfo { buildable = False })
+                  , Executable "Dummy Two" "/tmp" getExecutableScopeUnknown  emptyBuildInfo ]
+#else
+    let execs = [ Executable "Dummy One" "/tmp" (emptyBuildInfo { buildable = False })
+                  , Executable "Dummy Two" "/tmp" emptyBuildInfo ]
+#endif
+    let actual = getMacAppsForBuildableExecutors [] execs
+    let expected = [ MacApp "Dummy Two" Nothing Nothing [] [] DoNotChase ]
+    assertEqual "two mac-apps should be built" expected actual
+
+testBuildMacApp_twoAppsAndTwoExecutablesOneBuildableOneNot :: Assertion
+testBuildMacApp_twoAppsAndTwoExecutablesOneBuildableOneNot = do
+#if MIN_VERSION_Cabal(2,0,0)
+    let execs = [ Executable "Dummy One" "/tmp" getExecutableScopeUnknown (emptyBuildInfo { buildable = False })
+                  , Executable "Dummy Two" "/tmp" getExecutableScopeUnknown  emptyBuildInfo ]
+#else
+    let execs = [ Executable "Dummy One" "/tmp" (emptyBuildInfo { buildable = False })
+                  , Executable "Dummy Two" "/tmp" emptyBuildInfo ]
+#endif
+    let apps = [ MacApp "Dummy One" Nothing Nothing [] [] DoNotChase
+                 , MacApp "Dummy Two" Nothing Nothing [] [] DoNotChase ]
+    let actual = getMacAppsForBuildableExecutors apps execs
+    let expected = [ MacApp "Dummy Two" Nothing Nothing [] [] DoNotChase ]
+    assertEqual "one mac-app should be built" expected actual
diff --git a/tests/Main.hs b/tests/Main.hs
new file mode 100644
--- /dev/null
+++ b/tests/Main.hs
@@ -0,0 +1,9 @@
+module Main (main) where
+
+import Test.Framework (defaultMain)
+import Distribution.MacOSX.Internal.Tests (macosxInternalTests)
+
+main :: IO ()
+main = defaultMain
+  [ macosxInternalTests
+  ]
