diff --git a/Lastik.cabal b/Lastik.cabal
--- a/Lastik.cabal
+++ b/Lastik.cabal
@@ -1,5 +1,5 @@
 Name:               Lastik
-Version:            0.5
+Version:            0.6.1
 License:            BSD3
 License-File:       LICENSE
 Author:             Tony Morris <code@tmorris.net>
@@ -7,32 +7,35 @@
 Synopsis:           A library for compiling programs in a variety of languages
 Category:           Development
 Description:        A library for compiling programs in a variety of languages including Java, Scala and C#.
+Homepage:           http://code.google.com/p/lastik
 Cabal-version:      >= 1.2
 Build-Type:         Simple
-Extra-Source-Files: README
 
 Flag small_base
   Description:     Choose the new, split-up base package.
 
 Library
   if flag(small_base)
-    Build-Depends: base < 4 && >= 3, bytestring, directory, filepath, process, zip-archive, pureMD5, SHA
+    Build-Depends: base < 4 && >= 3, bytestring, directory, filepath, process, zip-archive, pureMD5, SHA, containers
   else
-    Build-Depends: base < 3, filepath, process, zip-archive, pureMD5, SHA
+    Build-Depends: base < 3, filepath, process, zip-archive, pureMD5, SHA, containers
 
   GHC-Options:    -Wall
   Exposed-Modules:
-          Lastik.Compile,
-          Lastik.Directory,
-          Lastik.Extension,
-          Lastik.Find,
-          Lastik.Output,
-          Lastik.Runner,
-          Lastik.Util,
-          Lastik.Java.Javac,
-          Lastik.Java.Javadoc,
-          Lastik.Scala.Access,
-          Lastik.Scala.Debug,
-          Lastik.Scala.Scalac,
-          Lastik.Scala.Scaladoc,
-          Lastik.Scala.Target
+          System.Build,
+          System.Build.FilePather,
+          System.Build.Args,
+          System.Build.Runner,
+          System.Build.Scala.Access,
+          System.Build.Scala.Debug,
+          System.Build.Scala.Scalac,
+          System.Build.Scala.Scaladoc,
+          System.Build.Scala.Target,
+          System.Build.Command,
+          System.Build.CompilePaths,
+          System.Build.Extensions,
+          System.Build.OutputDirectory,
+          System.Build.OutputReferenceGet,
+          System.Build.OutputReferenceSet,
+          System.Build.Java.Javac,
+          System.Build.Java.Javadoc
diff --git a/Lastik/Compile.hs b/Lastik/Compile.hs
deleted file mode 100644
--- a/Lastik/Compile.hs
+++ /dev/null
@@ -1,31 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-
--- | A module for representing data types that can be compiled by taking a list of files.
-module Lastik.Compile (
-                       Compile,
-                       compile,
-                       environmentCommand
-                      ) where
-
-import Control.Monad
-import Data.List
-import Data.Maybe
-import System.Directory
-import System.Cmd
-import System.Exit
-import System.Environment
-import System.FilePath
-
--- | A class of compilable data types.
-class Compile c where
-  compile :: c -> [FilePath] -> String
-
-instance Compile [Char] where
-  compile s _ = s
-
-instance Compile ([FilePath] -> String) where
-  compile = id
-
-environmentCommand :: String -> String -> IO String
-environmentCommand v c = (\e -> (case lookup v e of Nothing -> c
-                                                    Just k -> k </> c) ++ " ") `fmap` getEnvironment
diff --git a/Lastik/Directory.hs b/Lastik/Directory.hs
deleted file mode 100644
--- a/Lastik/Directory.hs
+++ /dev/null
@@ -1,104 +0,0 @@
--- | A module for performing operations on directories.
-module Lastik.Directory(
-                        chdir,
-                        archiveDirectories,
-                        writeArchive,
-                        writeHashArchive,
-                        copyDir,
-                        dropRoot,
-                        dropRoot',
-                        mkdir,
-                        rmdir
-                        ) where
-
-import System.Directory
-import System.FilePath
-import Lastik.Find
-import Codec.Archive.Zip
-import qualified Data.ByteString.Lazy as B
-import Control.Monad
-import Control.Exception
-import Data.Digest.Pure.MD5
-import Data.Digest.Pure.SHA
-
--- | Change to the given directory, then execute the given action, then change back to the original directory.
-chdir :: FilePath -- ^ The directory to change to.
-         -> IO a  -- ^ The action to execute in the given directory.
-         -> IO a  -- ^ The result of executing the given action.
-chdir d a = bracket getCurrentDirectory setCurrentDirectory (\_ -> setCurrentDirectory d >> a)
-
--- | Create a zip archive by changing into directories and archiving the contents.
-archiveDirectories :: [(FilePath, FilePath)] -- ^ A list of base directories to change to and contents of that directory to archive.
-                      -> RecursePredicate  -- ^ The recursion predicate to search for files to archive.
-                      -> FilterPredicate     -- ^ The filter predicate to search for files to archive.
-                      -> [ZipOption]         -- ^ The options during the creation of the archive.
-                      -> IO Archive          -- ^ The constructed archive.
-archiveDirectories dirs rp fp opts = foldM (\a (d, f) -> chdir d $ do j <- find rp fp f
-                                                                      addFilesToArchive opts a j) emptyArchive dirs
-
--- | Writes a zip archive to a file.
-writeArchive :: [(FilePath, FilePath)] -- ^ A list of base directories to change to and contents of that directory to archive.
-                -> RecursePredicate  -- ^ The recursion predicate to search for files to archive.
-                -> FilterPredicate     -- ^ The filter predicate to search for files to archive.
-                -> [ZipOption]         -- ^ The options during the creation of the archive.
-                -> FilePath            -- ^ The file to write the archive to.
-                -> IO ()
-writeArchive dirs rp fp opts f = do a <- archiveDirectories dirs rp fp opts
-                                    B.writeFile f (fromArchive a)
-
--- | Writes a zip archive to a file then computes a MD5 and SHA1 hash and writes them to files with @".md5"@ and @".sha1"@ extensions.
-writeHashArchive :: [(FilePath, FilePath)] -- ^ A list of base directories to change to and contents of that directory to archive.
-                    -> RecursePredicate  -- ^ The recursion predicate to search for files to archive.
-                    -> FilterPredicate     -- ^ The filter predicate to search for files to archive.
-                    -> [ZipOption]         -- ^ The options during the creation of the archive.
-                    -> FilePath            -- ^ The file to write the archive to and the prefix name of the files containing the hashes.
-                    -> IO ()
-writeHashArchive dirs rp fp opts f = do a <- archiveDirectories dirs rp fp opts
-                                        let s = fromArchive a
-                                        B.writeFile f s
-                                        forM_ [(show . md5, "md5"), (show . sha1, "sha1")] (\(k, a) -> writeFile (f <.> a) (k s))
-
--- | Copy the contents of a directory to another, perhaps trimming parent directories.
-copyDir :: RecursePredicate -- ^ The recursion predicate to search for files in the source directory.
-           -> FilterPredicate -- ^ The filter predicate to search for files in the source directory.
-           -> Int             -- ^ The number of parent directories to drop before copying to the target directory.
-           -> FilePath        -- ^ The source directory.
-           -> FilePath        -- ^ The target directory.
-           -> IO ()
-copyDir rp fp levels from to = do s <- find rp fp from
-                                  forM_ s (\f -> let d = dropRoot' levels f
-                                                 in do mkdir (to </> dropFileName d)
-                                                       copyFile f (to </> d))
-
--- | Drops the parent directory of a given file path.
---
--- > dropRoot "/foo/bar" == "/bar"
--- > dropRoot "foo/bar" == "bar"
--- > dropRoot "foo" == ""
--- > dropRoot "" == ""
-dropRoot :: FilePath  -- ^ The file path to drop the parent directory from.
-            -> String -- ^ The file path without a parent directory.
-dropRoot [] = []
-dropRoot (x:xs) = (if x == pathSeparator then id else drop 1) (dropWhile (/= pathSeparator) xs)
-
--- | Drops the parent directory ('dropRoot') of a given file path multiple times.
---
--- > dropRoot' 0 "/foo/bar" == "/foo/bar"
--- > dropRoot' 1 "/foo/bar" == "/bar"
--- > dropRoot' 1 "foo/bar" == "bar"
--- > dropRoot' 2 "foo/bar" == ""
--- > dropRoot' 10 "foo/bar" == ""
-dropRoot' :: Int         -- ^ The number of times to drop the parent directory.
-             -> FilePath -- ^ The file path to drop parent directories from.
-             -> FilePath -- ^ Te file path without parent directories.
-dropRoot' n k = (iterate dropRoot k) !! (if n < 0 then 0 else n)
-
--- | Creates the given directory and its parents if it doesn't exist.
-mkdir :: FilePath -- ^ The directory to create.
-         -> IO ()
-mkdir = createDirectoryIfMissing True
-
--- | Removes the given directory recursively if it exists.
-rmdir :: FilePath -- ^ The directory to remove.
-         -> IO ()
-rmdir d = doesDirectoryExist d >>= flip when (removeDirectoryRecursive d)
diff --git a/Lastik/Extension.hs b/Lastik/Extension.hs
deleted file mode 100644
--- a/Lastik/Extension.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-
--- | A module for data types that can have a file extension inferred. e.g. A @Javac@ data type compiles source files with a @java@ file extension.
-module Lastik.Extension(
-                        ext',
-                        Extension(..)
-                       ) where
-
-import Lastik.Output
-import Lastik.Compile
-
--- | A class of data types that can have a file extension inferred.
-class Extension e where
-  ext :: e -> String
-
-instance Extension [Char] where
-  ext = id
-
--- | Prepends a @"."@ to the given extension.
-ext' :: (Extension e) => e -> String
-ext' e = '.' : ext e
diff --git a/Lastik/Find.hs b/Lastik/Find.hs
deleted file mode 100644
--- a/Lastik/Find.hs
+++ /dev/null
@@ -1,192 +0,0 @@
-module Lastik.Find where
-
-import Control.Applicative
-import Control.Monad
-import Control.Monad.Instances
-import Data.Monoid
-import System.FilePath
-import System.Directory
-import qualified System.FilePath as P
-import Lastik.Util
-
-newtype FilePather a = FilePather {
-  (<?>) :: FilePath -> a
-}
-
-instance Functor FilePather where
-  fmap f (FilePather k) = FilePather (f . k)
-
-instance Applicative FilePather where
-  FilePather f <*> FilePather a = FilePather (f <*> a)
-  pure = FilePather . const
-
-instance Monad FilePather where
-  FilePather f >>= k = FilePather (f >>= (<?>) . k)
-  return = pure
-
-instance (Monoid a) => Monoid (FilePather a) where
-  mempty = return mempty
-  FilePather x `mappend` FilePather y = FilePather (x `mappend` y)
-
-filePather :: (FilePath -> a) -> FilePather a
-filePather = FilePather
-
-filePath :: FilePather FilePath
-filePath = filePather id
-
-always :: FilePather Bool
-always = filePather (\_ -> True)
-
-always' :: FilePather (a -> Bool)
-always' = constant always
-
-never :: FilePather Bool
-never = filePather (\_ -> False)
-
-never' :: FilePather (a -> Bool)
-never' = constant never
-
-extension :: FilePather FilePath
-extension = filePather takeExtension
-
-extension' :: FilePather (a -> FilePath)
-extension' = constant extension
-
-directory :: FilePather FilePath
-directory = filePather takeDirectory
-
-directory' :: FilePather (a -> FilePath)
-directory' = constant directory
-
-hasExtension :: FilePather Bool
-hasExtension = filePather P.hasExtension
-
-hasExtension' :: FilePather (a -> Bool)
-hasExtension' = constant Lastik.Find.hasExtension
-
-splitExtension :: FilePather (String, String)
-splitExtension = filePather P.splitExtension
-
-splitExtension' :: FilePather (a -> (String, String))
-splitExtension' = constant Lastik.Find.splitExtension
-
-splitDirectories :: FilePather [FilePath]
-splitDirectories = filePather P.splitDirectories
-
-splitDirectories' :: FilePather (a -> [FilePath])
-splitDirectories' = constant Lastik.Find.splitDirectories
-
-hasTrailingPathSeparator :: FilePather Bool
-hasTrailingPathSeparator = filePather P.hasTrailingPathSeparator
-
-hasTrailingPathSeparator' :: FilePather (a -> Bool)
-hasTrailingPathSeparator' = constant Lastik.Find.hasTrailingPathSeparator
-
-fileName :: FilePather FilePath
-fileName = filePather takeFileName
-
-fileName' :: FilePather (a -> FilePath)
-fileName' = constant fileName
-
-baseName :: FilePather FilePath
-baseName = filePather takeBaseName
-
-baseName' :: FilePather (a -> FilePath)
-baseName' = constant baseName
-
-normalise :: FilePather FilePath
-normalise = filePather P.normalise
-
-normalise' :: FilePather (a -> FilePath)
-normalise' = constant Lastik.Find.normalise
-
-makeValid :: FilePather FilePath
-makeValid = filePather P.makeValid
-
-makeValid' :: FilePather (a -> FilePath)
-makeValid' = constant Lastik.Find.makeValid
-
-isRelative :: FilePather Bool
-isRelative = filePather P.isRelative
-
-isRelative' :: FilePather (a -> Bool)
-isRelative' = constant Lastik.Find.isRelative
-
-isAbsolute :: FilePather Bool
-isAbsolute = filePather P.isAbsolute
-
-isAbsolute' :: FilePather (a -> Bool)
-isAbsolute' = constant Lastik.Find.isAbsolute
-
-isValid :: FilePather Bool
-isValid = filePather P.isValid
-
-isValid' :: FilePather (a -> Bool)
-isValid' = constant Lastik.Find.isValid
-
-not' :: (Functor f) => f Bool -> f Bool
-not' = fmap not
-
-constant :: (Functor f) => f a -> f (t -> a)
-constant p = fmap const p
-
-(==?) :: (Eq a, Functor f) => f a -> a -> f Bool
-p ==? a = fmap (a ==) p
-
-(/=?) :: (Eq a, Functor f) => f a -> a -> f Bool
-p /=? a = fmap (a /=) p
-
-(==>) :: (Applicative f) => f Bool -> f Bool -> f Bool
-(==>) = liftA2 (\p q -> not p || q)
-
-(===>) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
-(===>) = liftA2 (==>)
-
-(/=>) :: (Applicative f) => f Bool -> f Bool -> f Bool
-(/=>) = liftA2 (\p q -> not q && p)
-
-(/==>) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
-(/==>) = liftA2 (/=>)
-
-(&&?) :: (Applicative f) => f Bool -> f Bool -> f Bool
-(&&?) = liftA2 (&&)
-
-(?&&?) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
-(?&&?) = liftA2 (&&?)
-
-(||?) :: (Applicative f) => f Bool -> f Bool -> f Bool
-(||?) = liftA2 (||)
-
-(?||?) :: (Applicative f1, Applicative f2) => f1 (f2 Bool) -> f1 (f2 Bool) -> f1 (f2 Bool)
-(?||?) = liftA2 (||?)
-
-data FileType = File | Directory | Unknown deriving (Eq, Show)
-
-type RecursePredicate = FilePather Bool
-type FilterPredicate = FilePather (FileType -> Bool)
-
-isFile :: (Applicative f) => f (FileType -> Bool)
-isFile = pure (== File)
-
-isDirectory :: (Applicative f) => f (FileType -> Bool)
-isDirectory = pure (== Directory)
-
-isUnknown :: (Applicative f) => f (FileType -> Bool)
-isUnknown = pure (== Unknown)
-
-find :: RecursePredicate -> FilterPredicate -> FilePath -> IO [FilePath]
-find = find' []
-  where
-  find' :: FilePath -> RecursePredicate -> FilterPredicate -> FilePath -> IO [FilePath]
-  find' k r f p = let z = if null k then p else k </> p
-                      z' t = if f <?> z $ t then [z] else []
-                  in ifM (doesFileExist z)
-                       (return (z' File)) $
-                       do e <- doesDirectoryExist z
-                          if e
-                            then if r <?> z
-                                   then do c <- getDirectoryContents z
-                                           t <- fmap join $ forM (filter (`notElem` [".", ".."]) c) (find' k r f . (z </>))
-                                           return (z' Directory ++ t)
-                                   else return (z' Directory)
-                            else return (z' Unknown)
diff --git a/Lastik/Java/Javac.hs b/Lastik/Java/Javac.hs
deleted file mode 100644
--- a/Lastik/Java/Javac.hs
+++ /dev/null
@@ -1,222 +0,0 @@
--- | A module for compiling Java source files using @javac@.
-module Lastik.Java.Javac(
-                         Debug(..),
-                         Proc,
-                         noneProc,
-                         only,
-                         proc',
-                         Implicit,
-                         noneImplicit,
-                         class',
-                         implicit',
-                         Javac,
-                         debug,
-                         nowarn,
-                         verbose,
-                         deprecation,
-                         classpath,
-                         sourcepath,
-                         bootclasspath,
-                         extdirs,
-                         endorseddirs,
-                         proc,
-                         processor,
-                         processorpath,
-                         directory,
-                         src,
-                         implicit,
-                         encoding,
-                         source,
-                         target,
-                         version,
-                         help,
-                         akv,
-                         flags,
-                         etc,
-                         javac,
-                         javac'
-                        )where
-
-import Lastik.Util
-import Lastik.Compile
-import Lastik.Extension
-import Lastik.Output
-import Data.List
-import Control.Arrow
-
--- | The debug options that can be passed to @javac@.
-data Debug = Lines    -- ^ Generate only some debugging info (@lines@).
-             | Vars   -- ^ Generate only some debugging info (@vars@).
-             | Source -- ^ Generate only some debugging info (@source@).
-             | None   -- ^ Generate no debugging info.
-             | All    -- ^ Generate all debugging info.
-             deriving Eq
-
-instance Show Debug where
-  show Lines = "lines"
-  show Vars = "vars"
-  show Source = "source"
-  show None = "none"
-  show All = "all"
-
--- | Control whether annotation processing and/or compilation is done.
-newtype Proc = Proc Bool deriving Eq
-
--- | No annotation processing (@none@).
-noneProc :: Proc
-noneProc = Proc False
-
--- | Only annotation processing (@only@).
-only :: Proc
-only = Proc True
-
--- | Returns the second argument if the given @Proc@ is @none@, otherwise the third argument.
-proc' :: Proc -> a -> a -> a
-proc' (Proc False) _ f = f
-proc' (Proc True) t _ = t
-
-instance Show Proc where
-  show (Proc False) = "none"
-  show (Proc True) = "only"
-
--- | Specify whether or not to generate class files for implicitly referenced files.
-newtype Implicit = Implicit Bool deriving Eq
-
--- | No generate class files for implicitly referenced files (@none@).
-noneImplicit :: Implicit
-noneImplicit = Implicit False
-
--- | Generate class files for implicitly referenced files (@class@).
-class' :: Implicit
-class' = Implicit True
-
--- | Returns the second argument if the given @Implicit@ is @none@, otherwise the third argument.
-implicit' :: Implicit -> a -> a -> a
-implicit' (Implicit False) _ f = f
-implicit' (Implicit True) t _ = t
-
-instance Show Implicit where
-  show (Implicit False) = "none"
-  show (Implicit True) = "class"
-
--- | Javac is the compiler for Java source files.
-data Javac = Javac {
-  debug :: Maybe Debug,                  -- ^ @-g@
-  nowarn :: Bool,                        -- ^ @-nowarn@
-  verbose :: Bool,                       -- ^ @-verbose@
-  deprecation :: Bool,                   -- ^ @-deprecation@
-  classpath :: [FilePath],               -- ^ @-classpath@
-  sourcepath :: [FilePath],              -- ^ @-sourcepath@
-  bootclasspath :: [FilePath],           -- ^ @-bootclasspath@
-  extdirs :: [FilePath],                 -- ^ @-extdirs@
-  endorseddirs :: [FilePath],            -- ^ @-endorseddirs@
-  proc :: Maybe Proc,                    -- ^ @-proc@
-  processor :: [String],                 -- ^ @-processor@
-  processorpath :: Maybe FilePath,       -- ^ @-processorpath@
-  directory :: Maybe FilePath,           -- ^ @-d@
-  src :: Maybe FilePath,                 -- ^ @-s@
-  implicit :: Maybe Implicit,            -- ^ @-implicit@
-  encoding :: Maybe String,              -- ^ @-encoding@
-  source :: Maybe String,                -- ^ @-source@
-  target :: Maybe String,                -- ^ @-target@
-  version :: Bool,                       -- ^ @-version@
-  help :: Bool,                          -- ^ @-help@
-  akv :: Maybe ([String], Maybe String), -- ^ @-Akey[=value]@
-  flags :: [String],                     -- ^ @-J@
-  etc :: Maybe String
-}
-
--- | A @Javac@ with nothing set.
-javac :: Javac
-javac = Javac Nothing False False False [] [] [] [] [] Nothing [] Nothing Nothing Nothing Nothing Nothing Nothing Nothing False False Nothing [] Nothing
-
--- | Construct a @Javac@.
-javac' :: Maybe Debug
-         -> Bool
-         -> Bool
-         -> Bool
-         -> [FilePath]
-         -> [FilePath]
-         -> [FilePath]
-         -> [FilePath]
-         -> [FilePath]
-         -> Maybe Proc
-         -> [String]
-         -> Maybe FilePath
-         -> Maybe FilePath
-         -> Maybe FilePath
-         -> Maybe Implicit
-         -> Maybe String
-         -> Maybe String
-         -> Maybe String
-         -> Bool
-         -> Bool
-         -> Maybe ([String], Maybe String)
-         -> [String]
-         -> Maybe String
-         -> Javac
-javac' = Javac
-
-instance Show Javac where
-  show (Javac debug
-              nowarn
-              verbose
-              deprecation
-              classpath
-              sourcepath
-              bootclasspath
-              extdirs
-              endorseddirs
-              proc
-              processor
-              processorpath
-              directory
-              src
-              implicit
-              encoding
-              source
-              target
-              version
-              help
-              akv
-              flags
-              etc) = [d debug,
-                      "nowarn" ~~ nowarn,
-                      "verbose" ~~ verbose,
-                      "deprecation" ~~ deprecation,
-                      "classpath" ~?? classpath,
-                      "sourcepath" ~?? sourcepath,
-                      "bootclasspath" ~?? bootclasspath,
-                      "extdirs" ~?? extdirs,
-                      "endorseddirs" ~?? extdirs,
-                      "proc" ~~> show $ proc,
-                      uncons [] ((intercalate "," .) . (:)) processor,
-                      "processorpath" ~~~> processorpath,
-                      "d" ~~> id $ directory,
-                      "s" ~~> id $ src,
-                      "implicit" ~~> show $ implicit,
-                      "encoding" ~~~> encoding,
-                      "source" ~~~> source,
-                      "target" ~~~> target,
-                      "version" ~~ version,
-                      "help" ~~ help,
-                      (\z -> "-A" ++ case first (intercalate ".") z of (k, Just v) -> k ++ '=' : v
-                                                                       (k, Nothing) -> k) ~? akv,
-                      intercalate " " $ map ("-J" ++) flags,
-                      id ~? etc] ^^^ " "
-                      where
-                        d (Just All) = "g" ~~ True
-                        d k = "g" -~> show $ k
-
-instance Compile Javac where
-  compile s ps = "javac " ++ show s ++ ' ' : space ps
-
-instance Output Javac where
-  output = directory
-
-instance Extension Javac where
-  ext _ = "java"
-
-instance OutputReference Javac where
-  reference p j = j { classpath = p }
-  reference' = classpath
diff --git a/Lastik/Java/Javadoc.hs b/Lastik/Java/Javadoc.hs
deleted file mode 100644
--- a/Lastik/Java/Javadoc.hs
+++ /dev/null
@@ -1,344 +0,0 @@
--- | A module for documenting Java source files using @javadoc@.
-module Lastik.Java.Javadoc(
-                           SourceRelease(..),
-                           Javadoc,
-                           overview,
-                           public,
-                           protected,
-                           package,
-                           private,
-                           help,
-                           doclet,
-                           docletpath,
-                           sourcepath,
-                           classpath,
-                           exclude,
-                           subpackages,
-                           breakiterator,
-                           bootclasspath,
-                           source,
-                           extdirs,
-                           verbose,
-                           locale,
-                           encoding,
-                           quiet,
-                           flags,
-                           directory,
-                           use,
-                           version,
-                           author,
-                           docfilessubdirs,
-                           splitindex,
-                           windowtitle,
-                           doctitle,
-                           header,
-                           footer,
-                           top,
-                           bottom,
-                           link,
-                           linkoffline,
-                           excludedocfilessubdir,
-                           group,
-                           nocomment,
-                           nodeprecated,
-                           noqualifier,
-                           nosince,
-                           notimestamp,
-                           nodeprecatedlist,
-                           notree,
-                           noindex,
-                           nohelp,
-                           nonavbar,
-                           serialwarn,
-                           tag,
-                           taglet,
-                           tagletpath,
-                           charset,
-                           helpfile,
-                           linksource,
-                           sourcetab,
-                           keywords,
-                           stylesheetfile,
-                           docencoding,
-                           javadoc,
-                           javadoc'
-                          ) where
-
-import Lastik.Util
-import Lastik.Compile
-import Lastik.Output
-import Lastik.Extension
-import Data.List hiding (group)
-
--- | Provide source compatibility with specified release
-data SourceRelease = S15   -- ^ @1.5@
-                     | S14 -- ^ @1.4@
-                     | S13 -- ^ @1.3@
-                     deriving Eq
-
-instance Show SourceRelease where
-  show S15 = "1.5"
-  show S14 = "1.4"
-  show S13 = "1.3"
-
--- | Javadoc is the compiler for Java API documentation.
-data Javadoc = Javadoc {
-  overview :: Maybe FilePath,        -- ^ @-overview@
-  public :: Bool,                    -- ^ @-public@
-  protected :: Bool,                 -- ^ @-protected@
-  package :: Bool,                   -- ^ @-package@
-  private :: Bool,                   -- ^ @-private@
-  help :: Bool,                      -- ^ @-help@
-  doclet :: Maybe String,            -- ^ @-doclet@
-  docletpath :: Maybe FilePath,      -- ^ @-docletpath@
-  sourcepath :: [FilePath],          -- ^ @-sourcepath@
-  classpath :: [FilePath],           -- ^ @-classpath@
-  exclude :: [String],               -- ^ @-exclude@
-  subpackages :: [String],           -- ^ @-subpackages@
-  breakiterator :: Bool,             -- ^ @-breakiterator@
-  bootclasspath :: [FilePath],       -- ^ @-bootclasspath@
-  source :: Maybe SourceRelease,     -- ^ @-source@
-  extdirs :: [FilePath],             -- ^ @-extdirs@
-  verbose :: Bool,                   -- ^ @-verbose@
-  locale :: Maybe String,            -- ^ @-locale@
-  encoding :: Maybe String,          -- ^ @-encoding@
-  quiet :: Bool,                     -- ^ @-quiet@
-  flags :: [String],                 -- ^ @-flags@
-  directory :: Maybe FilePath,       -- ^ @-d@
-  use :: Bool,                       -- ^ @-use@
-  version :: Bool,                   -- ^ @-version@
-  author :: Bool,                    -- ^ @-author@
-  docfilessubdirs :: Bool,           -- ^ @-docfilessubdirs@
-  splitindex :: Bool,                -- ^ @-splitindex@
-  windowtitle :: Maybe String,       -- ^ @-windowtitle@
-  doctitle :: Maybe String,          -- ^ @-doctitle@
-  header :: Maybe String,            -- ^ @-header@
-  footer :: Maybe String,            -- ^ @-footer@
-  top :: Maybe String,               -- ^ @-top@
-  bottom :: Maybe String,            -- ^ @-bottom@
-  link :: [String],                  -- ^ @-link@
-  linkoffline :: [(String, String)], -- ^ @-linkoffline@
-  excludedocfilessubdir :: [String], -- ^ @-excludedocfilessubdir@
-  group :: [(String, [String])],     -- ^ @-group@
-  nocomment :: Bool,                 -- ^ @-nocomment@
-  nodeprecated :: Bool,              -- ^ @-nodeprecated@
-  noqualifier :: [String],           -- ^ @-noqualifier@
-  nosince :: Bool,                   -- ^ @-nosince@
-  notimestamp :: Bool,               -- ^ @-notimestamp@
-  nodeprecatedlist :: Bool,          -- ^ @-nodeprecatedlist@
-  notree :: Bool,                    -- ^ @-notree@
-  noindex :: Bool,                   -- ^ @-noindex@
-  nohelp :: Bool,                    -- ^ @-nohelp@
-  nonavbar :: Bool,                  -- ^ @-nonavbar@
-  serialwarn :: Bool,                -- ^ @-serialwarn@
-  tag :: [(String, String, String)], -- ^ @-tag@
-  taglet :: Bool,                    -- ^ @-taglet@
-  tagletpath :: Bool,                -- ^ @-tagletpath@
-  charset :: Maybe String,           -- ^ @-charset@
-  helpfile :: Maybe FilePath,        -- ^ @-helpfile@
-  linksource :: Bool,                -- ^ @-linksource@
-  sourcetab :: Maybe Int,            -- ^ @-sourcetab@
-  keywords :: Bool,                  -- ^ @-keywords@
-  stylesheetfile :: Maybe FilePath,  -- ^ @-stylesheetfile@
-  docencoding :: Maybe String        -- ^ @-docencoding@
-}
-
--- | A @Javadoc@ with nothing set.
-javadoc :: Javadoc
-javadoc = Javadoc Nothing False False False False False Nothing Nothing [] [] [] [] False [] Nothing [] False Nothing Nothing False [] Nothing False False False False False Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] [] False False [] False False False False False False False False [] False False Nothing Nothing False Nothing False Nothing Nothing
-
--- | Construct a @Javadoc@.
-javadoc' :: Maybe FilePath
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Maybe String
-            -> Maybe FilePath
-            -> [FilePath]
-            -> [FilePath]
-            -> [String]
-            -> [String]
-            -> Bool
-            -> [FilePath]
-            -> Maybe SourceRelease
-            -> [FilePath]
-            -> Bool
-            -> Maybe String
-            -> Maybe String
-            -> Bool
-            -> [String]
-            -> Maybe FilePath
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Maybe String
-            -> Maybe String
-            -> Maybe String
-            -> Maybe String
-            -> Maybe String
-            -> Maybe String
-            -> [String]
-            -> [(String, String)]
-            -> [String]
-            -> [(String, [String])]
-            -> Bool
-            -> Bool
-            -> [String]
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> Bool
-            -> [(String, String, String)]
-            -> Bool
-            -> Bool
-            -> Maybe String
-            -> Maybe FilePath
-            -> Bool
-            -> Maybe Int
-            -> Bool
-            -> Maybe FilePath
-            -> Maybe String
-            -> Javadoc
-javadoc' = Javadoc
-
-instance Show Javadoc where
-  show (Javadoc overview
-                public
-                protected
-                package
-                private
-                help
-                doclet
-                docletpath
-                sourcepath
-                classpath
-                exclude
-                subpackages
-                breakiterator
-                bootclasspath
-                source
-                extdirs
-                verbose
-                locale
-                encoding
-                quiet
-                flags
-                directory
-                use
-                version
-                author
-                docfilessubdirs
-                splitindex
-                windowtitle
-                doctitle
-                header
-                footer
-                top
-                bottom
-                link
-                linkoffline
-                excludedocfilessubdir
-                group
-                nocomment
-                nodeprecated
-                noqualifier
-                nosince
-                notimestamp
-                nodeprecatedlist
-                notree
-                noindex
-                nohelp
-                nonavbar
-                serialwarn
-                tag
-                taglet
-                tagletpath
-                charset
-                helpfile
-                linksource
-                sourcetab
-                keywords
-                stylesheetfile
-                docencoding) = ["overview" ~~~> overview,
-                                "public" ~~ public,
-                                "protected" ~~ protected,
-                                "package" ~~ package,
-                                "private" ~~ private,
-                                "help" ~~ help,
-                                "doclet" ~~~> doclet,
-                                "docletpath" ~~~> docletpath,
-                                "sourcepath" ~?? sourcepath,
-                                "classpath" ~?? classpath,
-                                c exclude,
-                                c subpackages,
-                                "breakiterator" ~~ breakiterator,
-                                "bootclasspath" ~?? bootclasspath,
-                                "source" ~~> show $ source,
-                                "extdirs" ~?? extdirs,
-                                "verbose" ~~ verbose,
-                                "locale" ~~~> locale,
-                                "encoding" ~~~> encoding,
-                                "quiet" ~~ quiet,
-                                intercalate " " $ map ("-J" ++) flags,
-                                "d" ~~~> directory,
-                                "use" ~~ use,
-                                "version" ~~ version,
-                                "author" ~~ author,
-                                "docfilessubdirs" ~~ docfilessubdirs,
-                                "splitindex" ~~ splitindex,
-                                "windowtitle" ~~~> windowtitle,
-                                "doctitle" ~~~> doctitle,
-                                "header" ~~~> header,
-                                "footer" ~~~> footer,
-                                "top" ~~~> top,
-                                "bottom" ~~~> bottom,
-                                "link" `many` link,
-                                manys (\(x, y) -> x ++ "\" \"" ++ y) "linkoffline" linkoffline,
-                                intercalate ":" excludedocfilessubdir,
-                                manys (\(x, y) -> x ++ "\" \"" ++ c y) "group" group,
-                                "nocomment" ~~ nocomment,
-                                "nodeprecated" ~~ nodeprecated,
-                                intercalate ":" noqualifier,
-                                "nosince" ~~ nosince,
-                                "notimestamp" ~~ notimestamp,
-                                "nodeprecatedlist" ~~ nodeprecatedlist,
-                                "notree" ~~ notree,
-                                "noindex" ~~ noindex,
-                                "nohelp" ~~ nohelp,
-                                "nonavbar" ~~ nonavbar,
-                                "serialwarn" ~~ serialwarn,
-                                manys (\(x, y, z) -> c [x, y, z]) "tag" tag,
-                                "taglet" ~~ taglet,
-                                "tagletpath" ~~ tagletpath,
-                                "charset" ~~~> charset,
-                                "helpfile" ~~~> helpfile,
-                                "linksource" ~~ linksource,
-                                "sourcetab" ~~> show $ sourcetab,
-                                "keywords" ~~ keywords,
-                                "stylesheetfile" ~~~> stylesheetfile,
-                                "docencoding" ~~~> docencoding
-                                ] ^^^ " "
-                                where
-                                c = intercalate ":"
-
-instance Compile Javadoc where
-  compile s ps = "javadoc " ++ show s ++ ' ' : space ps
-
-
-instance Output Javadoc where
-  output = directory
-
-instance Extension Javadoc where
-  ext _ = "java"
-
-instance OutputReference Javadoc where
-  reference p j = j { classpath = p }
-  reference' = classpath
diff --git a/Lastik/Output.hs b/Lastik/Output.hs
deleted file mode 100644
--- a/Lastik/Output.hs
+++ /dev/null
@@ -1,90 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-
--- | A module for data types that have an output file(s) target and/or can reference a target. e.g. The @Javac@ data type might have an output target given by the @-d@ option and references a target by the @-classpath@ option.
-module Lastik.Output(
-                     Output(..),
-                     OutputReference(..),
-                     (<=+=>),
-                     (<=++=>),
-                     (>===>),
-                     (>=>=>),
-                     outref,
-                     (<==>),
-                     (<===>)
-                    ) where
-
-import Control.Monad
-import Control.Monad.Instances
-import Data.Maybe
-import System.Directory
-import Lastik.Find
-
--- | A class of data types that have a potential output target.
-class Output o where
-  output :: o -> Maybe FilePath
-
-instance Output (Maybe FilePath) where
-  output = id
-
-instance Output [FilePath] where
-  output = listToMaybe
-
--- | A class of data types that can reference an output target.
-class OutputReference r where
-  reference :: [FilePath] -> r -> r
-  reference' :: r -> [FilePath]
-
--- | Adds the given file path to the reference target of the given value.
-(<=+=>) :: (OutputReference r) =>
-           FilePath -- ^ The file path to add.
-           -> r     -- ^ The value to add the given file path to.
-           -> r     -- ^ The value with the given file path added.
-v <=+=> k = reference (v : reference' k) k
-
--- | Adds the given file paths to the reference target of the given value.
-(<=++=>) :: (OutputReference r) =>
-            [FilePath] -- ^ The file paths to add.
-            -> r       -- ^ The value to add the given file paths to.
-            -> r       -- ^ The value with the given file paths added.
-v <=++=> k = reference (v ++ reference' k) k
-
--- | Adds the (potential) output target of the given value to the output target of the given value.
-(>===>) :: (Output o, OutputReference r) =>
-           o    -- ^ The value with an output target value to add.
-           -> r -- ^ The value to add the output target to.
-           -> r -- ^ The value after the output target has been added.
-v >===> w = case output v of Nothing -> w
-                             Just y -> y <=+=> w
-
--- | Adds the (potential) output target and output references of the given value to the output target of the given value.
-(>=>=>) :: (Output o, OutputReference o, OutputReference r) =>
-           o    -- ^ The value with an output target and output references to add.
-           -> r -- ^ The value to add the output target and output references to.
-           -> r -- ^ The value after the output target has been added.
-v >=>=> w = v >===> (reference' v <=++=> w)
-
--- | Adds the output target to the output reference of the given value.
-outref :: (Output o, OutputReference o) =>
-          o    -- ^ The value to add the output target to its output reference.
-          -> o
-outref = join (>===>)
-
--- | Returns all existing files of the second argument that have a later last-modification time than the latest of all existing files in the first argument.
-(<==>) :: [FilePath]       -- ^ The set of file paths to compute the latest modification time.
-          -> [FilePath]    -- ^ The set of file paths to filter and keep those that have a later modification time.
-          -> IO [FilePath] -- ^ The file paths with a later last-modification time than the latest in the first argument.
-d <==> s = do e <- filterM (\k -> liftM2 (||) (doesFileExist k) (doesDirectoryExist k)) d
-              if null e
-                then return s
-                else do filterM (\z -> liftM2 (>) (getModificationTime z) (fmap maximum $ mapM getModificationTime e)) s
-
--- | Returns all existing files of the second argument that have a later last-modification time than all files (recursively) in the output target of the the first argument.
-(<===>) :: (Output o) =>
-           o                -- ^ The value to compute the output target and recursively search for the latest last-modification time.
-           -> [FilePath]    -- ^ The set of file paths to filter and keep those that have a later modification time.
-           -> IO [FilePath] -- ^ The file paths with a later last-modification time than the latest in the output target of the first argument.
-d <===> s = case output d of Nothing -> return s
-                             Just k -> do e <- doesDirectoryExist k
-                                          if e
-                                            then find always always' k >>= (\t -> t <==> s)
-                                            else return s
diff --git a/Lastik/Runner.hs b/Lastik/Runner.hs
deleted file mode 100644
--- a/Lastik/Runner.hs
+++ /dev/null
@@ -1,112 +0,0 @@
--- | A module for running compilable data types that take a list of file paths to compile.
-module Lastik.Runner(
-                     Runner,
-                     runner,
-                     runnerPath,
-                     codeRunner,
-                     pathRunner,
-                     valueRunner,
-                     andThen,
-                     ifRun,
-                     (+++),
-                     (-+-),
-                     pathTransform,
-                     (!!!),
-                     (>->),
-                     (+>->),
-                     (->-),
-                     (+->-)
-                    ) where
-
-import Data.Maybe
-import System.Cmd
-import System.Directory
-import System.Exit
-import Lastik.Find
-import Lastik.Compile
-import Lastik.Extension
-import Lastik.Output
-
--- | A runner takes a list of file paths and runs a system command on them.
-type Runner r = r -> [FilePath] -> IO ExitCode
-
--- | A runner that can access its arguments.
-runner :: (r -> [FilePath] -> Runner r) -> Runner r
-runner f = (\c p -> (f c p) c p)
-
--- | A runner that can access its list of file paths.
-runnerPath :: ([FilePath] -> Runner r) -> Runner r
-runnerPath = runner . const
-
--- | A runner that can access its data type value.
-runnerValue :: (r -> Runner r) -> Runner r
-runnerValue = runner . (const .)
-
--- | A runner that always produces the given exit code.
-codeRunner :: ExitCode -> Runner r
-codeRunner c = \_ _ -> return c
-
--- | A runner that ignores its data type value.
-pathRunner :: ([FilePath] -> IO ExitCode) -> Runner r
-pathRunner f = \_ -> f
-
--- | A runner that ignores its list of file paths.
-valueRunner :: (r -> IO ExitCode) -> Runner r
-valueRunner f = const . f
-
--- | Executes an action using runner arguments then produces a runner with the value of the previous action.
-andThen :: (r -> [FilePath] -> IO a) -> (a -> Runner r) -> Runner r
-andThen f g = \c p -> f c p >>= \k -> (g k) c p
-
--- | Executes an action using runner arguments then produces a runner.
-andThen' :: (r -> [FilePath] -> IO a) -> Runner r -> Runner r
-andThen' = (. const) . andThen
-
--- | Execute the second runner only if the exit code of the first runner satisfies the given predicate.
-ifRun :: (ExitCode -> Bool) -> Runner r -> Runner r -> Runner r
-ifRun z j k = \c p -> do j' <- j c p
-                         if z j'
-                           then k c p
-                           else return j'
-
--- | Execute the second runner only if the exit code of the first runner is @ExitSuccess@.
-(+++) :: Runner r -> Runner r -> Runner r
-(+++) = ifRun (== ExitSuccess)
-
--- | Execute the second runner only if the exit code of the first runner is not @ExitSuccess@.
-(-+-) :: Runner r -> Runner r -> Runner r
-(-+-) = ifRun (/= ExitSuccess)
-
--- | Transform the list of file paths before executing the runner.
-pathTransform :: ([FilePath] -> IO [FilePath]) -> Runner t -> Runner t
-pathTransform k f = \c p -> do v <- k p
-                               f c v
-
--- | Get all file paths with the given file extension (recursively) and execute the runner on those.
-pathTransform' :: (Extension e) => e -> Runner r -> Runner r
-pathTransform' = pathTransform . recurse
-  where
-  recurse c p = fmap concat $ find always (constant $ extension ==? ext' c) `mapM` p
-
--- | Execute the compile result as a system command.
-(!!!) :: (Compile c) => Runner c
-(!!!) = (system .) . compile
-
--- | Create the output target directory then execute the compile result as a system command.
-(>->) :: (Output c, Compile c) => Runner c
-(>->) = (const . mkdirectory . output) `andThen'` (!!!)
-  where
-  mkdirectory s = createDirectoryIfMissing True `mapM_` maybeToList s
-
--- | Create the output target directory then incrementally execute the compile result as a system command. The output target is searched for the latest last-modification time and only those files in the output reference that are modified later than this time are submitted for compilation.
-(+>->) :: (Output c, Compile c, OutputReference c) => Runner c
-(+>->) = \c p -> do d <- c <===> p
-                    if null d then return ExitSuccess else (>->) (outref c) d
-
--- | A runner that recursively searches the output target for files that match a given extension and compiles them as a system command.
-(->-) :: (Output c, Extension c, Compile c) => Runner c
-(->-) = runnerValue (flip pathTransform' (>->))
-
--- | A runner that recursively searches the output target for files that match a given extension and compiles them incrementally as a system command. The output target is searched for the latest last-modification time and only those files in the output reference that are modified later than this time are submitted for compilation.
-(+->-) :: (Output r, Extension r, Compile r, OutputReference r) => Runner r
-(+->-) = runnerValue (flip pathTransform' (+>->))
diff --git a/Lastik/Scala/Access.hs b/Lastik/Scala/Access.hs
deleted file mode 100644
--- a/Lastik/Scala/Access.hs
+++ /dev/null
@@ -1,15 +0,0 @@
--- | A module that represents that access levels available to @scaladoc@.
-module Lastik.Scala.Access(
-                           Access(..)
-                          ) where
-
--- | Show only public, protected/public (default) or all classes and members (public,protected,private)
-data Access = Public      -- ^ @public@
-              | Protected -- ^ @protected@
-              | Private   -- ^ @private@
-              deriving Eq
-
-instance Show Access where
-  show Public = "public"
-  show Protected = "protected"
-  show Private = "private"
diff --git a/Lastik/Scala/Debug.hs b/Lastik/Scala/Debug.hs
deleted file mode 100644
--- a/Lastik/Scala/Debug.hs
+++ /dev/null
@@ -1,19 +0,0 @@
--- | A module that represents the debug levels to @scalac@ and @scaladoc@.
-module Lastik.Scala.Debug(
-                          Debug(..)
-                         )where
-
--- | Specify level of generated debugging info (none,source,line,vars,notailcalls)
-data Debug = None          -- ^ @none@
-             | Source      -- ^ @source@
-             | Line        -- ^ @line@
-             | Vars        -- ^ @vars@
-             | NoTailCalls -- ^ @notailcalls@
-             deriving Eq
-
-instance Show Debug where
-  show None = "none"
-  show Source = "source"
-  show Line = "line"
-  show Vars = "vars"
-  show NoTailCalls = "notailcalls"
diff --git a/Lastik/Scala/Scalac.hs b/Lastik/Scala/Scalac.hs
deleted file mode 100644
--- a/Lastik/Scala/Scalac.hs
+++ /dev/null
@@ -1,183 +0,0 @@
--- | A module for compiling Scala source files using @scalac@.
-module Lastik.Scala.Scalac(
-                           Scalac,
-                           debug,
-                           nowarn,
-                           verbose,
-                           deprecation,
-                           unchecked,
-                           classpath,
-                           sourcepath,
-                           bootclasspath,
-                           extdirs,
-                           directory,
-                           encoding,
-                           target,
-                           print,
-                           optimise,
-                           explaintypes,
-                           uniqid,
-                           version,
-                           help,
-                           (#),
-                           etc,
-                           scalac,
-                           scalac',
-                           kscalac,
-                           Fsc,
-                           fscalac,
-                           reset,
-                           shutdown,
-                           server,
-                           flags,
-                           fsc
-                          )where
-
-import Prelude hiding (print)
-import Lastik.Util
-import Lastik.Compile
-import Lastik.Extension
-import Lastik.Output
-import Lastik.Scala.Debug
-import Lastik.Scala.Target
-import Data.List
-import System.Exit
-
--- | Scalac is the compiler for Scala source files.
-data Scalac = Scalac {
-  debug :: Maybe Debug,        -- ^ @-g@
-  nowarn :: Bool,              -- ^ @-nowarn@
-  verbose :: Bool,             -- ^ @-verbose@
-  deprecation :: Bool,         -- ^ @-deprecation@
-  unchecked :: Bool,           -- ^ @-unchecked@
-  classpath :: [FilePath],     -- ^ @-classpath@
-  sourcepath :: [FilePath],    -- ^ @-sourcepath@
-  bootclasspath :: [FilePath], -- ^ @-bootclasspath@
-  extdirs :: [FilePath],       -- ^ @-extdirs@
-  directory :: Maybe FilePath, -- ^ @-d@
-  encoding :: Maybe String,    -- ^ @-encoding@
-  target :: Maybe Target,      -- ^ @-target@
-  print :: Bool,               -- ^ @-print@
-  optimise :: Bool,            -- ^ @-optimise@
-  explaintypes :: Bool,        -- ^ @-explaintypes@
-  uniqid :: Bool,              -- ^ @-uniqid@
-  version :: Bool,             -- ^ @-version@
-  help :: Bool,                -- ^ @-help@
-  (#) :: Maybe FilePath,       -- ^ @\@@
-  etc :: Maybe String
-}
-
--- | A @Scalac@ with nothing set.
-scalac :: Scalac
-scalac = Scalac Nothing False False False False [] [] [] [] Nothing Nothing Nothing False False False False False False Nothing Nothing
-
--- | Construct a @Scalac@.
-scalac' :: Maybe Lastik.Scala.Debug.Debug
-           -> Bool
-           -> Bool
-           -> Bool
-           -> Bool
-           -> [FilePath]
-           -> [FilePath]
-           -> [FilePath]
-           -> [FilePath]
-           -> Maybe FilePath
-           -> Maybe String
-           -> Maybe Target
-           -> Bool
-           -> Bool
-           -> Bool
-           -> Bool
-           -> Bool
-           -> Bool
-           -> Maybe FilePath
-           -> Maybe String
-           -> Scalac
-scalac' = Scalac
-
--- | Convert the given scalac to a list of command line options which may be used by other scala tools.
-kscalac :: Scalac -> [String]
-kscalac (Scalac debug
-                 nowarn
-                 verbose
-                 deprecation
-                 unchecked
-                 classpath
-                 sourcepath
-                 bootclasspath
-                 extdirs
-                 directory
-                 encoding
-                 target
-                 print
-                 optimise
-                 explaintypes
-                 uniqid
-                 version
-                 help
-                 script
-                 etc) = ["g" -~> show $ debug,
-                         "nowarn" ~~ nowarn,
-                         "verbose" ~~ verbose,
-                         "deprecation" ~~ deprecation,
-                         "unchecked" ~~ unchecked,
-                         "classpath" ~?? classpath,
-                         "sourcepath" ~?? sourcepath,
-                         "bootclasspath" ~?? bootclasspath,
-                         "extdirs" ~?? extdirs,
-                         "d" ~~~> directory,
-                         "encoding" ~~~> encoding,
-                         "target" -~> show $ target,
-                         "print" ~~ print,
-                         "optimise" ~~ optimise,
-                         "explaintypes" ~~ explaintypes,
-                         "uniqid" ~~ uniqid,
-                         "version" ~~ version,
-                         "help" ~~ help,
-                         ((:) '@') ~? script,
-                         id ~? etc]
-
-instance Show Scalac where
-  show s = kscalac s ^^^ " "
-
-instance Compile Scalac where
-  compile s ps = "scalac " ++ show s ++ ' ' : space ps
-
-instance Output Scalac where
-  output = directory
-
-instance Extension Scalac where
-  ext _ = "scala"
-
-instance OutputReference Scalac where
-  reference p s = s { classpath = p }
-  reference' = classpath
-
--- | The Scala fast compiler (@fsc@).
-data Fsc = Fsc {
-  fscalac :: Scalac,                -- ^ The scalac options to use.
-  reset :: Bool,                    -- ^ @-reset@
-  shutdown :: Bool,                 -- ^ @-shutdown@
-  server :: Maybe (String, String), -- ^ @-server@
-  flags :: [String]                 -- ^ @-flags@
-}
-
-instance Show Fsc where
-  show (Fsc fscalac reset shutdown server flags) = (kscalac fscalac ++ ["reset" ~~ reset, "shutdown" ~~ shutdown, (uncurry (++)) ~? server, intercalate " " (fmap ("-J" ++) flags)]) ^^^ " "
-
-instance Compile Fsc where
-  compile f ps = "fsc " ++ show f ++ ' ' : space ps
-
-instance Output Fsc where
-  output = directory . fscalac
-
-instance Extension Fsc where
-  ext _ = "scala"
-
-instance OutputReference Fsc where
-  reference p f = let s = fscalac f in f { fscalac = reference p s }
-  reference' = reference' . fscalac
-
--- | A @Fsc@ with nothing set.
-fsc :: Fsc
-fsc = Fsc scalac False False Nothing []
diff --git a/Lastik/Scala/Scaladoc.hs b/Lastik/Scala/Scaladoc.hs
deleted file mode 100644
--- a/Lastik/Scala/Scaladoc.hs
+++ /dev/null
@@ -1,177 +0,0 @@
--- | A module for documenting Scala source files using @scaladoc@.
-module Lastik.Scala.Scaladoc(
-                             Scaladoc,
-                             debug,
-                             nowarn,
-                             verbose,
-                             deprecation,
-                             unchecked,
-                             classpath,
-                             sourcepath,
-                             bootclasspath,
-                             extdirs,
-                             directory,
-                             encoding,
-                             target,
-                             print,
-                             optimise,
-                             explaintypes,
-                             uniqid,
-                             version,
-                             help,
-                             (#),
-                             access,
-                             bottom,
-                             charset,
-                             doctitle,
-                             footer,
-                             header,
-                             linksource,
-                             nocomment,
-                             stylesheetfile,
-                             top,
-                             windowtitle,
-                             etc,
-                             scaladoc,
-                             scaladoc'
-                            )where
-
-import Prelude hiding (print)
-import Lastik.Util
-import Lastik.Scala.Target
-import Lastik.Scala.Debug
-import Lastik.Scala.Access
-import Lastik.Scala.Scalac (kscalac, scalac')
-import Lastik.Compile
-import Lastik.Output
-import Lastik.Extension
-
--- | Javadoc is the compiler for Scala API documentation.
-data Scaladoc = Scaladoc {
-  debug :: Maybe Debug,           -- ^ @-g@
-  nowarn :: Bool,                 -- ^ @-nowarn@
-  verbose :: Bool,                -- ^ @-verbose@
-  deprecation :: Bool,            -- ^ @-deprecation@
-  unchecked :: Bool,              -- ^ @-unchecked@
-  classpath :: [FilePath],        -- ^ @-classpath@
-  sourcepath :: [FilePath],       -- ^ @-sourcepath@
-  bootclasspath :: [FilePath],    -- ^ @-bootclasspath@
-  extdirs :: [FilePath],          -- ^ @-extdirs@
-  directory :: Maybe FilePath,    -- ^ @-d@
-  encoding :: Maybe String,       -- ^ @-encoding@
-  target :: Maybe Target,         -- ^ @-target@
-  print :: Bool,                  -- ^ @-print@
-  optimise :: Bool,               -- ^ @-optimise@
-  explaintypes :: Bool,           -- ^ @-explaintypes@
-  uniqid :: Bool,                 -- ^ @-uniqid@
-  version :: Bool,                -- ^ @-version@
-  help :: Bool,                   -- ^ @-help@
-  (#) :: Maybe FilePath,          -- ^ @\@@
-  access :: Maybe Access,         -- ^ @-access@
-  bottom :: Maybe String,         -- ^ @-bottom@
-  charset :: Maybe String,        -- ^ @-charset@
-  doctitle :: Maybe String,       -- ^ @-doctitle@
-  footer :: Maybe String,         -- ^ @-footer@
-  header :: Maybe String,         -- ^ @-header@
-  linksource :: Bool,             -- ^ @-linksource@
-  nocomment :: Bool,              -- ^ @-nocomment@
-  stylesheetfile :: Maybe String, -- ^ @-stylesheetfile@
-  top :: Maybe String,            -- ^ @-top@
-  windowtitle :: Maybe String,    -- ^ @-windowtitle@
-  etc :: Maybe String
-}
-
--- | A @Scaladoc@ with nothing set.
-scaladoc :: Scaladoc
-scaladoc = Scaladoc Nothing False False False False [] [] [] [] Nothing Nothing Nothing False False False False False False Nothing Nothing Nothing Nothing Nothing Nothing Nothing False False Nothing Nothing Nothing Nothing
-
--- | Construct a @Scaladoc@.
-scaladoc' :: Maybe Debug
-             -> Bool
-             -> Bool
-              -> Bool
-             -> Bool
-             -> [FilePath]
-             -> [FilePath]
-             -> [FilePath]
-             -> [FilePath]
-             -> Maybe FilePath
-             -> Maybe String
-             -> Maybe Target
-             -> Bool
-             -> Bool
-             -> Bool
-             -> Bool
-             -> Bool
-             -> Bool
-             -> Maybe FilePath
-             -> Maybe Access
-             -> Maybe String
-             -> Maybe String
-             -> Maybe String
-             -> Maybe String
-             -> Maybe String
-             -> Bool
-             -> Bool
-             -> Maybe String
-             -> Maybe String
-             -> Maybe String
-             -> Maybe String
-             -> Scaladoc
-scaladoc' = Scaladoc
-
-instance Show Scaladoc where
-  show (Scaladoc debug
-                 nowarn
-                 verbose
-                 deprecation
-                 unchecked
-                 classpath
-                 sourcepath
-                 bootclasspath
-                 extdirs
-                 directory
-                 encoding
-                 target
-                 print
-                 optimise
-                 explaintypes
-                 uniqid
-                 version
-                 help
-                 script
-                 access
-                 bottom
-                 charset
-                 doctitle
-                 footer
-                 header
-                 linksource
-                 nocomment
-                 stylesheetfile
-                 top
-                 windowtitle
-                 etc) = (kscalac (scalac' debug nowarn verbose deprecation unchecked classpath sourcepath bootclasspath extdirs directory encoding target print optimise explaintypes uniqid version help script etc) ++ ["access" -~> show $ access,
-                                      "bottom" ~~~> bottom,
-                                      "charset" ~~~> charset,
-                                      "doctitle" ~~~> doctitle,
-                                      "footer" ~~~> footer,
-                                      "header" ~~~> header,
-                                      "linksource" ~~ linksource,
-                                      "nocomment" ~~ nocomment,
-                                      "stylesheetfile" ~~~> stylesheetfile,
-                                      "top" ~~~> top,
-                                      "windowtitle" ~~~> windowtitle]) ^^^ " "
-
-instance Compile Scaladoc where
-  compile s ps = "scaladoc " ++ show s ++ ' ' : space ps
-
-instance Output Scaladoc where
-  output = Lastik.Scala.Scaladoc.directory
-
-instance Extension Scaladoc where
-  ext _ = "scala"
-
-instance OutputReference Scaladoc where
-  reference p s = s { Lastik.Scala.Scaladoc.classpath = p }
-  reference' = Lastik.Scala.Scaladoc.classpath
diff --git a/Lastik/Scala/Target.hs b/Lastik/Scala/Target.hs
deleted file mode 100644
--- a/Lastik/Scala/Target.hs
+++ /dev/null
@@ -1,15 +0,0 @@
--- | A module that represents the target levels to @scalac@ and @scaladoc@.
-module Lastik.Scala.Target(
-                           Target(..)
-                          ) where
-
--- | Specify for which target object files should be built (jvm-1.5,jvm-1.4,msil)
-data Target = JVM1_5   -- ^ @jvm-1.5@
-              | JVM1_4 -- ^ @jvm-1.4@
-              | MSIL   -- ^ @msil@
-  deriving Eq
-
-instance Show Target where
-  show JVM1_5 = "jvm-1.5"
-  show JVM1_4 = "jvm-1.4"
-  show MSIL = "msil"
diff --git a/Lastik/Util.hs b/Lastik/Util.hs
deleted file mode 100644
--- a/Lastik/Util.hs
+++ /dev/null
@@ -1,142 +0,0 @@
-module Lastik.Util(
-                   (>>>>),
-                   (>>>>>),
-                   quote,
-                   (>===<),
-                   (~~),
-                   (~??),
-                   (~?),
-                   param,
-                   many,
-                   manys,
-                   (~~~~>),
-                   (~~~>),
-                   (~~>),
-                   (-~>),
-                   (^^^),
-                   space,
-                   space',
-                   uncons,
-                   ifM
-                  ) where
-
-import System.Exit
-import Control.Applicative hiding (many)
-import Control.Monad
-import Data.Maybe
-import Data.Monoid
-import Data.List
-import System.FilePath
-
--- | Applies the second value only if the first produces @ExitSuccess@.
-(>>>>) :: (Monad m) => m ExitCode -> m ExitCode -> m ExitCode
-f >>>> g = do e <- f
-              if e == ExitSuccess
-                then g
-                else return e
-
--- | Executes the second action only if the first produces @ExitSuccess@.
-(>>>>>) :: (Monad m) => m ExitCode -> m () -> m ()
-p >>>>> q = do e <- p
-               when (e == ExitSuccess) q
-
--- | Surrounds the given string in double-quotes.
-quote :: String -> String
-quote s = '"' : s ++ ['"']
-
--- | Surrounds each string in the list with double-quotes then intercalates the other given value.
-(>===<) :: String -> [String] -> String
-s >===< k = intercalate s (fmap quote k)
-
--- | An empty list if the boolean is @False@ otherwise the given string value with @'-'@ prepended.
-(~~) :: String -> Bool -> String
-g ~~ k = if k then '-' : g else []
-
--- | If the given list of file paths is empty, then returns the empty list. Otherwise prepend @'-'@ to the string followed by @' '@ then the search path separator intercalated in the list of file paths.
---
--- > Posix
--- > "123" ~?? ["abc", "def"] == "-123 \"abc\":\"def\""
--- > "123" ~?? ["abc", "def", "ghi"] == "-123 \"abc\":\"def\":\"ghi\""
-(~??) :: String -> [FilePath] -> String
-s ~?? [] = []
-s ~?? z = '-' : s ++ ' ' : [searchPathSeparator] >===< z
-
--- | If the given value is @Nothing@ return the empty list, otherwise run the given function.
-(~?) :: (k -> [a]) -> Maybe k -> [a]
-(~?) = maybe []
-
--- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ to the given string followed by the given character followed by surrounding the result of running the given function in double-quotes.
---
--- > param "abc" 'x' id (Just "tuv") == "-abcx\"tuv\""
--- > param "abc" 'x' id Nothing == ""
-param :: String -> Char -> (k -> String) -> Maybe k -> String
-param k c s = (~?) (\z -> '-' : k ++ c : quote (s z))
-
--- | A parameter with many values interspersed by @' '@.
---
--- > many "abc" ["tuv", "wxy"] == "-abc \"tuv\" -abc \"wxy\""
-many :: String -> [String] -> String
-many k v = intercalate " " $ map (k ~~~~>) v
-
--- | A parameter with many values interspersed by @' '@.
---
--- > manys id "abc" ["tuv", "wxy"] == "-abc \"tuv\" -abc \"wxy\""
-manys :: (a -> String) -> String -> [a] -> String
-manys f k v = many k (map f v)
-
--- | Prepends @'-'@ followed by the first value then @' '@ then the second value surrounded by double-quotes.
---
--- > "abc" ~~~~> "def" == "-abc \"def\""
-(~~~~>) :: String -> String -> String
-(~~~~>) = (. Just) . (~~~>)
-
--- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @' '@ then the second value surrounded by double-quotes.
---
--- > "abc" ~~~> Just "def" == "-abc \"def\""
--- > "abc" ~~~> Nothing == ""
-(~~~>) :: String -> Maybe String -> String
-(~~~>) = flip (~~>) id
-
--- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @' '@ followed by surrounding the result of running the given function in double-quotes.
---
--- > "abc" ~~> id $ Just "def" == "-abc \"def\""
--- > "abc" ~~> id $ Nothing == ""
-(~~>) :: String -> (k -> String) -> Maybe k -> String
-(~~>) = flip param ' '
-
--- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @':'@ followed by surrounding the result of running the given function in double-quotes.
---
--- > "abc" ~~> id $ Just "def" == "-abc:\"def\""
--- > "abc" ~~> id $ Nothing == ""
-(-~>) :: String -> (k -> String) -> Maybe k -> String
-(-~>) = flip param ':'
-
--- | Removes all empty lists from the first argument the intercalates the second argument.
---
--- > ["abc", "", "def"] ^^^ "x" == "abcxdef"
-(^^^) :: [[a]] -> [a] -> [a]
-g ^^^ t = Data.List.intercalate t (filter (not . null) g)
-
--- | Surrounds each given value in double-quotes then intercalates @' '@.
---
--- > space ["abc", "def"] == "\"abc\" \"def\""
-space :: [String] -> String
-space = (>===<) " "
-
--- | Intercalates @' '@.
---
--- > space' ["abc", "def"] == "abc def"
-space' :: [String] -> String
-space' = intercalate " "
-
--- | If the given list is empty return the first argument, otherwise run the given function on the head and tail.
-uncons :: a -> (b -> [b] -> a) -> [b] -> a
-uncons x _ [] = x
-uncons _ f (h:t) = f h t
-
--- | if/then/else with a lifted predicate.
-ifM :: (Monad f) => f Bool -> f a -> f a -> f a
-ifM c t f = do c' <- c
-               t' <- t
-               f' <- f
-               return (if c' then t' else f')
diff --git a/README b/README
deleted file mode 100644
--- a/README
+++ /dev/null
diff --git a/System/Build.hs b/System/Build.hs
new file mode 100644
--- /dev/null
+++ b/System/Build.hs
@@ -0,0 +1,37 @@
+module System.Build(
+  module System.Build.Command,
+  module System.Build.CompilePaths,
+  module System.Build.Directory,
+  module System.Build.Extensions,
+  module System.Build.FilePather,
+  module System.Build.OutputDirectory,
+  module System.Build.OutputReferenceGet,
+  module System.Build.OutputReferenceSet,
+  module System.Build.Args,
+  module System.Build.Runner,
+  module System.Build.Java.Javac,
+  module System.Build.Java.Javadoc,
+  module System.Build.Scala.Access,
+  module System.Build.Scala.Debug,
+  module System.Build.Scala.Scalac,
+  module System.Build.Scala.Scaladoc,
+  module System.Build.Scala.Target
+                   ) where
+
+import System.Build.Command
+import System.Build.CompilePaths
+import System.Build.Directory
+import System.Build.Extensions
+import System.Build.FilePather
+import System.Build.OutputDirectory
+import System.Build.OutputReferenceGet
+import System.Build.OutputReferenceSet
+import System.Build.Args
+import System.Build.Java.Javac(Javac)
+import System.Build.Java.Javadoc(Javadoc)
+import System.Build.Runner
+import System.Build.Scala.Access
+import System.Build.Scala.Debug
+import System.Build.Scala.Scalac(Scalac, Fsc)
+import System.Build.Scala.Scaladoc(Scaladoc)
+import System.Build.Scala.Target
diff --git a/System/Build/Args.hs b/System/Build/Args.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Args.hs
@@ -0,0 +1,144 @@
+-- | Functions for working with command line arguments and options.
+module System.Build.Args(
+                          quote,
+                          (~~),
+                          (~:),
+                          (~?),
+                          param,
+                          many,
+                          manys,
+                          (~~~>),
+                          (~~>),
+                          (-~>),
+                          (^^^),
+                          space,
+                          searchPath,
+                          tryEnvs
+                        ) where
+
+import Control.Monad
+import Data.Maybe
+import Data.List
+import qualified Data.Map as M
+import System.Environment
+import System.FilePath
+
+-- | Surrounds the given string in double-quotes.
+quote :: String
+         -> String
+quote s = '"' : s ++ "\""
+
+-- | An empty list if the boolean is @False@ otherwise the given string value with @'-'@ prepended.
+(~~) :: String
+        -> Bool
+        -> String
+g ~~ k = if k then '-' : g else []
+
+-- | If the given list of file paths is empty, then returns the empty list. Otherwise prepend @'-'@ to the string followed by @' '@ then the search path separator intercalated in the list of file paths.
+--
+-- > Posix
+-- > "123" ~?? ["abc", "def"] == "-123 \"abc\":\"def\""
+-- > "123" ~?? ["abc", "def", "ghi"] == "-123 \"abc\":\"def\":\"ghi\""
+(~:) :: String
+        -> [FilePath]
+        -> String
+_ ~: [] = []
+s ~: z = '-' : s ++ ' ' : [searchPathSeparator] >===< z
+
+-- | If the given value is @Nothing@ return the empty list, otherwise run the given function.
+(~?) :: (k -> [a])
+        -> Maybe k
+        -> [a]
+(~?) = maybe []
+
+-- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ to the given string followed by the given character followed by surrounding the result of running the given function in double-quotes.
+--
+-- > param "abc" 'x' id (Just "tuv") == "-abcx\"tuv\""
+-- > param "abc" 'x' id Nothing == ""
+param :: String
+         -> Char
+         -> (k -> String)
+         -> Maybe k
+         -> String
+param k c s = (~?) (\z -> '-' : k ++ c : quote (s z))
+
+-- | A parameter with many values interspersed by @' '@.
+--
+-- > many "abc" ["tuv", "wxy"] == "-abc \"tuv\" -abc \"wxy\""
+many :: String
+        -> [String]
+        -> String
+many k v = intercalate " " $ map (k ~~~>) v
+
+-- | A parameter with many values interspersed by @' '@.
+--
+-- > manys id "abc" ["tuv", "wxy"] == "-abc \"tuv\" -abc \"wxy\""
+manys :: (a -> String)
+         -> String
+         -> [a]
+         -> String
+manys f k = many k . map f
+
+-- | Prepends @'-'@ followed by the first value then @' '@ then the second value surrounded by double-quotes.
+--
+-- > "abc" ~~~> "def" == "-abc \"def\""
+(~~~>) :: String
+          -> String
+          -> String
+(~~~>) = (. Just) . (~~>)
+
+-- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @' '@ followed by surrounding the result of running the given function in double-quotes.
+--
+-- > "abc" ~~> Just "def" == "-abc \"def\""
+-- > "abc" ~~> Nothing == ""
+(~~>) :: (Show k) =>
+         String
+         -> Maybe k
+         -> String
+(~~>) k = param k ' ' show
+
+-- | If the given value is @Nothing@ return the empty list, otherwise prepend @'-'@ followed by the first value then @':'@ followed by surrounding the result of @show@ in double-quotes.
+--
+-- > "abc" ~~> Just "def" == "-abc:\"def\""
+-- > "abc" ~~> Nothing == ""
+(-~>) :: (Show k) =>
+         String
+         -> Maybe k
+         -> String
+(-~>) k = param k ':' show
+
+-- | Removes all empty lists from the first argument the intercalates the second argument.
+--
+-- > ["abc", "", "def"] ^^^ "x" == "abcxdef"
+(^^^) :: [[a]]
+         -> [a]
+         -> [a]
+g ^^^ t = Data.List.intercalate t (filter (not . null) g)
+
+-- | Surrounds each given value in double-quotes then intercalates @' '@.
+--
+-- > space ["abc", "def"] == "\"abc\" \"def\""
+space :: [String]
+         -> String
+space = (>===<) " "
+
+-- | Surrounds each given value in double-quotes then intercalates @[searchPathSeparator]@.
+--
+-- > searchPath ["abc", "def"] == "\"abc\":\"def\""
+searchPath :: [String]
+              -> String
+searchPath = (>===<) [searchPathSeparator]
+
+-- | Look up the given environment variables. The first one found that exists has its associated function called to produce a value.
+tryEnvs :: [(String, String -> a)]
+           -> IO (Maybe a)
+tryEnvs es = do e <- getEnvironment
+                let k [] = Nothing
+                    k ((a, b):t) = fmap b (a `M.lookup` M.fromList e) `mplus` k t   
+                return (k es)    
+
+
+-- not exported
+
+(>===<) :: String -> [String] -> String
+s >===< k = intercalate s (fmap quote k)
diff --git a/System/Build/Command.hs b/System/Build/Command.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Command.hs
@@ -0,0 +1,9 @@
+-- | Abstraction on executable commands.
+module System.Build.Command(
+                             Command,
+                             command
+                           ) where
+
+class Command c where
+  -- | Determines the executable command for a value. Since this is in @IO@ it may use environment variables.
+  command :: c -> IO String
diff --git a/System/Build/CompilePaths.hs b/System/Build/CompilePaths.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/CompilePaths.hs
@@ -0,0 +1,9 @@
+-- | For building a command for values that use paths.
+module System.Build.CompilePaths(
+                                  CompilePaths,
+                                  (=>>)
+                                ) where
+
+class CompilePaths c where
+  -- | Builds a command for a value given a list of file paths.
+  (=>>) :: c -> [FilePath] -> String
diff --git a/System/Build/Extensions.hs b/System/Build/Extensions.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Extensions.hs
@@ -0,0 +1,14 @@
+-- | Computing file extensions for a value.
+module System.Build.Extensions(
+                                Extensions,
+                                exts,
+                                exts'
+                              ) where
+
+class Extensions e where
+  -- Return all the file extensions associated with the given value.
+  exts :: e -> [String]
+
+-- | Return all the file extensions associated with the given value and prepend a single dot.
+exts' :: (Extensions e) => e -> [String]
+exts' = map ('.':) . exts
diff --git a/System/Build/FilePather.hs b/System/Build/FilePather.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/FilePather.hs
@@ -0,0 +1,386 @@
+-- | Combinators for finding files recursively. The combinators all surround the 'find' function.
+module System.Build.FilePather(
+                                FilePather,
+                                -- * Constructor and unwrapper
+                                (<?>),
+                                filePather,
+                                -- * Values using 'System.FilePath'
+                                filePath,
+                                always,
+                                always',
+                                never,
+                                never',
+                                extension,
+                                extension',
+                                directory,
+                                directory',
+                                hasExtension,
+                                hasExtension',
+                                splitExtension,
+                                splitExtension',
+                                splitDirectories,
+                                splitDirectories',
+                                hasTrailingPathSeparator,
+                                hasTrailingPathSeparator',
+                                fileName,
+                                fileName',
+                                baseName,
+                                baseName',
+                                normalise,
+                                normalise',
+                                makeValid,
+                                makeValid',
+                                isRelative,
+                                isRelative',
+                                isAbsolute,
+                                isAbsolute',
+                                isValid,
+                                isValid',
+                                -- * Utility
+                                not',
+                                constant,
+                                (==?),
+                                (/=?),
+                                (==||),
+                                (/=||),
+                                (==&&),
+                                (/=&&),
+                                (==>),
+                                (===>),
+                                (/=>),
+                                (/==>),
+                                (&&?),
+                                (?&&?),
+                                (||?),
+                                (?||?),
+                                -- * Find predicates
+                                FileType(..),
+                                RecursePredicate,
+                                FilterPredicate,
+                                isFile,
+                                isDirectory,
+                                isUnknown,
+                                -- * Core function
+                                find,
+                              ) where
+
+import Prelude hiding (any, all)
+import Control.Applicative
+import Control.Monad
+import Control.Monad.Instances
+import Data.Monoid
+import Data.Foldable(any, all, Foldable)
+import System.FilePath((</>), takeExtension, takeDirectory, takeFileName, takeBaseName)
+import System.Directory
+import qualified System.FilePath as P
+
+-- | A function that takes a 'FilePath' and produces a value.
+newtype FilePather a = FilePather {
+  (<?>) :: FilePath -> a
+}
+
+instance Functor FilePather where
+  fmap f (FilePather k) = FilePather (f . k)
+
+instance Applicative FilePather where
+  FilePather f <*> FilePather a = FilePather (f <*> a)
+  pure = FilePather . const
+
+instance Monad FilePather where
+  FilePather f >>= k = FilePather (f >>= (<?>) . k)
+  return = pure
+
+instance (Monoid a) => Monoid (FilePather a) where
+  mempty = return mempty
+  FilePather x `mappend` FilePather y = FilePather (x `mappend` y)
+
+-- | Construct a 'FilePather' from the given function
+filePather :: (FilePath -> a) ->
+              FilePather a
+filePather = FilePather
+
+-- | A value that runs the identity function.
+filePath :: FilePather FilePath
+filePath = filePather id
+
+-- | A value that always produces the value 'True'.
+always :: FilePather Bool
+always = filePather (const True)
+
+-- | A value using a constant function that produces the value 'True'.
+always' :: FilePather (a -> Bool)
+always' = constant always
+
+-- | A value that always produces the value 'False'.
+never :: FilePather Bool
+never = filePather (const False)
+
+-- | A value that always produces a constant function that produces the value 'False'.
+never' :: FilePather (a -> Bool)
+never' = constant never
+
+-- | A value that produces the extension of the given 'FilePath'.
+extension :: FilePather FilePath
+extension = filePather takeExtension
+
+-- | A value using a constant function that produces the extension of the given 'FilePath'.
+extension' :: FilePather (a -> FilePath)
+extension' = constant extension
+
+-- | A value that produces the directory of the given 'FilePath'.
+directory :: FilePather FilePath
+directory = filePather takeDirectory
+
+-- | A value using a constant function that produces the directory of the given 'FilePath'.
+directory' :: FilePather (a -> FilePath)
+directory' = constant directory
+
+-- | A value that produces a value denoting whether or not the given 'FilePath' has an extension.
+hasExtension :: FilePather Bool
+hasExtension = filePather P.hasExtension
+
+-- | A value using a constant function that produces a value denoting whether or not the given 'FilePath' has an extension.
+hasExtension' :: FilePather (a -> Bool)
+hasExtension' = constant hasExtension
+
+-- | A value that produces a value splitting the given 'FilePath' by its extension.
+splitExtension :: FilePather (String, String)
+splitExtension = filePather P.splitExtension
+
+-- | A value using a constant function that produces a value splitting the given 'FilePath' by its extension.
+splitExtension' :: FilePather (a -> (String, String))
+splitExtension' = constant splitExtension
+
+-- | A value that produces a value splitting the given 'FilePath' into its directories.
+splitDirectories :: FilePather [FilePath]
+splitDirectories = filePather P.splitDirectories
+
+-- | A value using a constant function that produces a value splitting the given 'FilePath' into its directories.
+splitDirectories' :: FilePather (a -> [FilePath])
+splitDirectories' = constant splitDirectories
+
+-- | A value that produces a value denoting whether or not the given 'FilePath' has a trailing path separator.
+hasTrailingPathSeparator :: FilePather Bool
+hasTrailingPathSeparator = filePather P.hasTrailingPathSeparator
+
+-- | A value using a constant function that produces a value denoting whether or not the given 'FilePath' has a trailing path separator.
+hasTrailingPathSeparator' :: FilePather (a -> Bool)
+hasTrailingPathSeparator' = constant hasTrailingPathSeparator
+
+-- | A value that produces the file name of the given 'FilePath'.
+fileName :: FilePather FilePath
+fileName = filePather takeFileName
+
+-- | A value using a constant function that produces the file name of the given 'FilePath'.
+fileName' :: FilePather (a -> FilePath)
+fileName' = constant fileName
+
+-- | A value that produces the base name of the given 'FilePath'.
+baseName :: FilePather FilePath
+baseName = filePather takeBaseName
+
+-- | A value using a constant function that produces the base name of the given 'FilePath'.
+baseName' :: FilePather (a -> FilePath)
+baseName' = constant baseName
+
+-- | A value that normalises the given 'FilePath'.
+normalise :: FilePather FilePath
+normalise = filePather P.normalise
+
+-- | A value using a constant function that normalises the given 'FilePath'.
+normalise' :: FilePather (a -> FilePath)
+normalise' = constant normalise
+
+-- | A value that makes valid the given 'FilePath'.
+makeValid :: FilePather FilePath
+makeValid = filePather P.makeValid
+
+-- | A value using a constant function that makes valid the given 'FilePath'.
+makeValid' :: FilePather (a -> FilePath)
+makeValid' = constant makeValid
+
+-- | A value that produces a value denoting whether or not the given 'FilePath' has is relative.
+isRelative :: FilePather Bool
+isRelative = filePather P.isRelative
+
+-- | A value using a constant function that produces a value denoting whether or not the given 'FilePath' has is relative.
+isRelative' :: FilePather (a -> Bool)
+isRelative' = constant isRelative
+
+-- | A value that produces a value denoting whether or not the given 'FilePath' has is absolute.
+isAbsolute :: FilePather Bool
+isAbsolute = filePather P.isAbsolute
+
+-- | A value using a constant function that produces a value denoting whether or not the given 'FilePath' has is absolute.
+isAbsolute' :: FilePather (a -> Bool)
+isAbsolute' = constant isAbsolute
+
+-- | A value that produces a value denoting whether or not the given 'FilePath' has is valid.
+isValid :: FilePather Bool
+isValid = filePather P.isValid
+
+-- | A value using a constant function that produces a value denoting whether or not the given 'FilePath' has is valid.
+isValid' :: FilePather (a -> Bool)
+isValid' = constant isValid
+
+-- | Inverts the given 'Bool' in a functor.
+not' :: (Functor f) =>
+        f Bool
+        -> f Bool
+not' = fmap not
+
+-- | Produces a constant function in a functor.
+constant :: (Functor f) =>
+            f a ->
+            f (t -> a)
+constant = fmap const
+
+-- | Tests for equality in a functor.
+(==?) :: (Eq a, Functor f) =>
+         f a
+         -> a
+         -> f Bool
+p ==? a = fmap (a ==) p
+
+-- | Tests for inequality in a functor.
+(/=?) :: (Eq a, Functor f) =>
+         f a
+         -> a
+         -> f Bool
+p /=? a = fmap (a /=) p
+
+-- | Tests for equality of @any@ values in the given container.
+(==||) :: (Eq a, Functor f, Foldable t) =>
+          f a ->
+          t a ->
+          f Bool
+p ==|| a = fmap (\x -> any (== x) a) p
+
+-- | Tests for inequality of @any@ values in the given container.
+(/=||) :: (Eq a, Functor f, Foldable t) =>
+          f a ->
+          t a ->
+          f Bool
+p /=|| a = fmap (\x -> any (/= x) a) p
+
+-- | Tests for equality of @all@ values in the given container.
+(==&&) :: (Eq a, Functor f, Foldable t) =>
+          f a ->
+          t a ->
+          f Bool
+p ==&& a = fmap (\x -> all (== x) a) p
+
+-- | Tests for inequality of @all@ values in the given container.
+(/=&&) :: (Eq a, Functor f, Foldable t) =>
+          f a ->
+          t a ->
+          f Bool
+p /=&& a = fmap (\x -> all (/= x) a) p
+
+-- | Tests for implication in an applicative functor.
+(==>) :: (Applicative f) =>
+         f Bool
+         -> f Bool
+         -> f Bool
+(==>) = liftA2 (\p q -> not p || q)
+
+-- | Tests for implication in an applicative functor in an applicative functor.
+(===>) :: (Applicative f1, Applicative f2) =>
+          f1 (f2 Bool)
+          -> f1 (f2 Bool)
+          -> f1 (f2 Bool)
+(===>) = liftA2 (==>)
+
+-- | Tests for inverse implication in an applicative functor.
+(/=>) :: (Applicative f) =>
+         f Bool 
+         -> f Bool
+         -> f Bool
+(/=>) = liftA2 (\p q -> not q && p)
+
+-- | Tests for inverse implication in an applicative functor in an applicative functor.
+(/==>) :: (Applicative f1, Applicative f2) =>
+          f1 (f2 Bool)
+          -> f1 (f2 Bool)
+          -> f1 (f2 Bool)
+(/==>) = liftA2 (/=>)
+
+-- | Performs conjunction (@AND@) in an applicative functor.
+(&&?) :: (Applicative f) =>
+         f Bool 
+         -> f Bool
+         -> f Bool
+(&&?) = liftA2 (&&)
+
+-- | Performs conjunction (@AND@) in an applicative functor in an applicative functor.
+(?&&?) :: (Applicative f1, Applicative f2) =>
+          f1 (f2 Bool)
+          -> f1 (f2 Bool)
+          -> f1 (f2 Bool)
+(?&&?) = liftA2 (&&?)
+
+-- | Performs disjunction (@OR@) in an applicative functor.
+(||?) :: (Applicative f) =>
+         f Bool
+         -> f Bool
+         -> f Bool
+(||?) = liftA2 (||)
+
+-- | Performs disjunction (@OR@) in an applicative functor in an applicative functor.
+(?||?) :: (Applicative f1, Applicative f2) =>
+          f1 (f2 Bool)
+          -> f1 (f2 Bool)
+          -> f1 (f2 Bool)
+(?||?) = liftA2 (||?)
+
+-- | The possible types of a file.
+data FileType = File -- ^ The type is a normal file.
+                | Directory -- ^ The type is a directory.
+                | Unknown -- ^ The type is unknown.
+  deriving (Eq, Show)
+
+-- | A recurse predicate takes a 'FilePath' and returns whether or not to continue recursing on that file.
+type RecursePredicate = FilePather Bool
+
+-- | A filter predicate takes a 'FilePath' and a file type and returns whether or not to filter the value.
+type FilterPredicate = FilePather (FileType -> Bool)
+
+-- | Compares for equivalence to a 'File' in an applicative functor.
+isFile :: (Applicative f) => 
+          f (FileType -> Bool)
+isFile = pure (== File)
+
+-- | Compares for equivalence to a 'Directory' in an applicative functor.
+isDirectory :: (Applicative f) =>
+               f (FileType -> Bool)
+isDirectory = pure (== Directory)
+
+-- | Compares for equivalence to 'Unknown' in an applicative functor.
+isUnknown :: (Applicative f) => 
+             f (FileType -> Bool)
+isUnknown = pure (== Unknown)
+
+-- | Finds all files using the given recurse predicate and filter predicate in the given file path.
+find :: RecursePredicate -- ^ The recurse predicate determines whether to continue recursing on the given file path.
+        -> FilterPredicate -- ^ The filter predicate determines whether to keep the current file path.
+        -> FilePath -- ^ The file path to begin finding files.
+        -> IO [FilePath] -- ^ All files found.
+find = find' []
+  where
+  find' :: FilePath -> RecursePredicate -> FilterPredicate -> FilePath -> IO [FilePath]
+  find' k r x p = let z = if null k then p else k </> p
+                      z' t = [z | x <?> z $ t]
+                      ifM c t f = do c' <- c
+                                     t' <- t
+                                     f' <- f
+                                     return (if c' then t' else f')
+                  in ifM (doesFileExist z)
+                       (return (z' File)) $
+                       do e <- doesDirectoryExist z
+                          if e
+                            then if r <?> z
+                                   then do c <- getDirectoryContents z
+                                           t <- fmap join $ forM (filter (`notElem` [".", ".."]) c) (find' k r x . (z </>))
+                                           return (z' Directory ++ t)
+                                   else return (z' Directory)
+                            else return (z' Unknown)
diff --git a/System/Build/Java/Javac.hs b/System/Build/Java/Javac.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Java/Javac.hs
@@ -0,0 +1,242 @@
+-- | A module for compiling Java source files using @javac@.
+module System.Build.Java.Javac(
+                                Javac,
+                                -- * Data types referenced by @Javac@
+                                Debug(..),
+                                Proc,
+                                Implicit,
+                                noneProc,
+                                only,
+                                proc',
+                                noneImplicit,
+                                class',
+                                implicit',
+                                -- * @Javac@ members
+                                debug,
+                                nowarn,
+                                verbose,
+                                deprecation,
+                                classpath,
+                                sourcepath,
+                                bootclasspath,
+                                extdirs,
+                                endorseddirs,
+                                proc,
+                                processor,
+                                processorpath,
+                                directory,
+                                src,
+                                implicit,
+                                encoding,
+                                source,
+                                target,
+                                version,
+                                help,
+                                akv,
+                                flags,
+                                etc,
+                                -- * @Javac@ values
+                                javac,
+                                javac'
+                                ) where
+
+import Data.List
+import Data.Maybe
+import Control.Arrow
+import Control.Monad
+import System.FilePath
+import System.Build.CompilePaths
+import System.Build.Extensions
+import System.Build.OutputDirectory
+import System.Build.OutputReferenceSet
+import System.Build.OutputReferenceGet
+import System.Build.Command
+import System.Build.Args
+
+-- | The debug options that can be passed to @javac@.
+data Debug = Lines    -- ^ Generate only some debugging info (@lines@).
+             | Vars   -- ^ Generate only some debugging info (@vars@).
+             | Source -- ^ Generate only some debugging info (@source@).
+             | None   -- ^ Generate no debugging info.
+             | All    -- ^ Generate all debugging info.
+             deriving Eq
+
+instance Show Debug where
+  show Lines = "lines"
+  show Vars = "vars"
+  show Source = "source"
+  show None = "none"
+  show All = "all"
+
+-- | Control whether annotation processing and/or compilation is done.
+newtype Proc = Proc Bool deriving Eq
+
+-- | No annotation processing (@none@).
+noneProc :: Proc
+noneProc = Proc False
+
+-- | Only annotation processing (@only@).
+only :: Proc
+only = Proc True
+
+-- | Returns the second argument if the given @Proc@ is @none@, otherwise the third argument.
+proc' :: Proc -> a -> a -> a
+proc' (Proc False) _ f = f
+proc' (Proc True) t _ = t
+
+instance Show Proc where
+  show (Proc False) = "none"
+  show (Proc True) = "only"
+
+-- | Specify whether or not to generate class files for implicitly referenced files.
+newtype Implicit = Implicit Bool deriving Eq
+
+-- | No generate class files for implicitly referenced files (@none@).
+noneImplicit :: Implicit
+noneImplicit = Implicit False
+
+-- | Generate class files for implicitly referenced files (@class@).
+class' :: Implicit
+class' = Implicit True
+
+-- | Returns the second argument if the given @Implicit@ is @none@, otherwise the third argument.
+implicit' :: Implicit -> a -> a -> a
+implicit' (Implicit False) _ f = f
+implicit' (Implicit True) t _ = t
+
+instance Show Implicit where
+  show (Implicit False) = "none"
+  show (Implicit True) = "class"
+
+-- | Javac is the compiler for Java source files.
+data Javac = Javac {
+  debug :: Maybe Debug,                  -- ^ @-g@
+  nowarn :: Bool,                        -- ^ @-nowarn@
+  verbose :: Bool,                       -- ^ @-verbose@
+  deprecation :: Bool,                   -- ^ @-deprecation@
+  classpath :: [FilePath],               -- ^ @-classpath@
+  sourcepath :: [FilePath],              -- ^ @-sourcepath@
+  bootclasspath :: [FilePath],           -- ^ @-bootclasspath@
+  extdirs :: [FilePath],                 -- ^ @-extdirs@
+  endorseddirs :: [FilePath],            -- ^ @-endorseddirs@
+  proc :: Maybe Proc,                    -- ^ @-proc@
+  processor :: [String],                 -- ^ @-processor@
+  processorpath :: Maybe FilePath,       -- ^ @-processorpath@
+  directory :: Maybe FilePath,           -- ^ @-d@
+  src :: Maybe FilePath,                 -- ^ @-s@
+  implicit :: Maybe Implicit,            -- ^ @-implicit@
+  encoding :: Maybe String,              -- ^ @-encoding@
+  source :: Maybe String,                -- ^ @-source@
+  target :: Maybe String,                -- ^ @-target@
+  version :: Bool,                       -- ^ @-version@
+  help :: Bool,                          -- ^ @-help@
+  akv :: Maybe ([String], Maybe String), -- ^ @-Akey[=value]@
+  flags :: [String],                     -- ^ @-J@
+  etc :: Maybe String
+}
+
+-- | A @Javac@ with nothing set.
+javac :: Javac
+javac = Javac Nothing False False False [] [] [] [] [] Nothing [] Nothing Nothing Nothing Nothing Nothing Nothing Nothing False False Nothing [] Nothing
+
+-- | Construct a @Javac@.
+javac' :: Maybe Debug
+         -> Bool
+         -> Bool
+         -> Bool
+         -> [FilePath]
+         -> [FilePath]
+         -> [FilePath]
+         -> [FilePath]
+         -> [FilePath]
+         -> Maybe Proc
+         -> [String]
+         -> Maybe FilePath
+         -> Maybe FilePath
+         -> Maybe FilePath
+         -> Maybe Implicit
+         -> Maybe String
+         -> Maybe String
+         -> Maybe String
+         -> Bool
+         -> Bool
+         -> Maybe ([String], Maybe String)
+         -> [String]
+         -> Maybe String
+         -> Javac
+javac' = Javac
+
+instance Show Javac where
+  show (Javac debug'
+              nowarn'
+              verbose'
+              deprecation'
+              classpath'
+              sourcepath'
+              bootclasspath'
+              extdirs'
+              endorseddirs'
+              proc''
+              processor'
+              processorpath'
+              directory'
+              src'
+              implicit''
+              encoding'
+              source'
+              target'
+              version'
+              help'
+              akv'
+              flags'
+              etc') = [d debug',
+                       "nowarn" ~~ nowarn',
+                       "verbose" ~~ verbose',
+                       "deprecation" ~~ deprecation',
+                       "classpath" ~: classpath',
+                       "sourcepath" ~: sourcepath',
+                       "bootclasspath" ~: bootclasspath',
+                       "extdirs" ~: extdirs',
+                       "endorseddirs" ~: endorseddirs',
+                       "proc" ~~> proc'',
+                       case processor' of [] -> []
+                                          _ -> intercalate "," processor',
+                       "processorpath" ~~> processorpath',
+                       "d" ~~> directory',
+                       "s" ~~> src',
+                       "implicit" ~~> implicit'',
+                       "encoding" ~~> encoding',
+                       "source" ~~> source',
+                       "target" ~~> target',
+                       "version" ~~ version',
+                       "help" ~~ help',
+                       (\z -> "-A" ++ case first (intercalate ".") z of (k, Just v) -> k ++ '=' : v
+                                                                        (k, Nothing) -> k) ~? akv',
+                       intercalate " " $ map ("-J" ++) flags',
+                       fromMaybe [] etc'] ^^^ " "
+                       where
+                         d (Just All) = "g" ~~ True
+                         d k = "g" -~> k
+
+instance CompilePaths Javac where
+  j =>> ps = show j ++ ' ' : space ps
+
+instance Extensions Javac where
+  exts _ = ["java"]
+
+instance OutputDirectory Javac where
+  outdir = directory
+
+instance OutputReferenceSet Javac where
+  setReference p j = j { classpath = p }
+
+instance OutputReferenceGet Javac where
+  getReference = classpath
+
+instance Command Javac where
+  command _ = let envs = [
+                            ("JAVA_HOME", (</> "bin" </> "javac")),
+                            ("JDK_HOME", (</> "bin" </> "javac")),
+                            ("JAVAC", id)
+                         ]
+              in fromMaybe "javac" `fmap` tryEnvs envs
diff --git a/System/Build/Java/Javadoc.hs b/System/Build/Java/Javadoc.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Java/Javadoc.hs
@@ -0,0 +1,362 @@
+-- | A module for documenting Java source files using @javadoc@.
+module System.Build.Java.Javadoc(
+                           Javadoc,
+                           -- * Data types references by @Javadoc@
+                           SourceRelease(..),
+                           -- * @Javadoc@ members
+                           overview,
+                           public,
+                           protected,
+                           package,
+                           private,
+                           help,
+                           doclet,
+                           docletpath,
+                           sourcepath,
+                           classpath,
+                           exclude,
+                           subpackages,
+                           breakiterator,
+                           bootclasspath,
+                           source,
+                           extdirs,
+                           verbose,
+                           locale,
+                           encoding,
+                           quiet,
+                           flags,
+                           directory,
+                           use,
+                           version,
+                           author,
+                           docfilessubdirs,
+                           splitindex,
+                           windowtitle,
+                           doctitle,
+                           header,
+                           footer,
+                           top,
+                           bottom,
+                           link,
+                           linkoffline,
+                           excludedocfilessubdir,
+                           group,
+                           nocomment,
+                           nodeprecated,
+                           noqualifier,
+                           nosince,
+                           notimestamp,
+                           nodeprecatedlist,
+                           notree,
+                           noindex,
+                           nohelp,
+                           nonavbar,
+                           serialwarn,
+                           tag,
+                           taglet,
+                           tagletpath,
+                           charset,
+                           helpfile,
+                           linksource,
+                           sourcetab,
+                           keywords,
+                           stylesheetfile,
+                           docencoding,
+                           -- * @Javadoc@ values
+                           javadoc,
+                           javadoc'
+                          ) where
+
+import Data.List hiding (group)
+import Data.Maybe
+import Control.Monad
+import System.FilePath
+import System.Build.Args
+import System.Build.CompilePaths
+import System.Build.Extensions
+import System.Build.OutputDirectory
+import System.Build.OutputReferenceSet
+import System.Build.OutputReferenceGet
+import System.Build.Command
+
+-- | Provide source compatibility with specified release
+data SourceRelease = S15   -- ^ @1.5@
+                     | S14 -- ^ @1.4@
+                     | S13 -- ^ @1.3@
+                     deriving Eq
+
+instance Show SourceRelease where
+  show S15 = "1.5"
+  show S14 = "1.4"
+  show S13 = "1.3"
+
+-- | Javadoc is the compiler for Java API documentation.
+data Javadoc = Javadoc {
+  overview :: Maybe FilePath,        -- ^ @-overview@
+  public :: Bool,                    -- ^ @-public@
+  protected :: Bool,                 -- ^ @-protected@
+  package :: Bool,                   -- ^ @-package@
+  private :: Bool,                   -- ^ @-private@
+  help :: Bool,                      -- ^ @-help@
+  doclet :: Maybe String,            -- ^ @-doclet@
+  docletpath :: Maybe FilePath,      -- ^ @-docletpath@
+  sourcepath :: [FilePath],          -- ^ @-sourcepath@
+  classpath :: [FilePath],           -- ^ @-classpath@
+  exclude :: [String],               -- ^ @-exclude@
+  subpackages :: [String],           -- ^ @-subpackages@
+  breakiterator :: Bool,             -- ^ @-breakiterator@
+  bootclasspath :: [FilePath],       -- ^ @-bootclasspath@
+  source :: Maybe SourceRelease,     -- ^ @-source@
+  extdirs :: [FilePath],             -- ^ @-extdirs@
+  verbose :: Bool,                   -- ^ @-verbose@
+  locale :: Maybe String,            -- ^ @-locale@
+  encoding :: Maybe String,          -- ^ @-encoding@
+  quiet :: Bool,                     -- ^ @-quiet@
+  flags :: [String],                 -- ^ @-flags@
+  directory :: Maybe FilePath,       -- ^ @-d@
+  use :: Bool,                       -- ^ @-use@
+  version :: Bool,                   -- ^ @-version@
+  author :: Bool,                    -- ^ @-author@
+  docfilessubdirs :: Bool,           -- ^ @-docfilessubdirs@
+  splitindex :: Bool,                -- ^ @-splitindex@
+  windowtitle :: Maybe String,       -- ^ @-windowtitle@
+  doctitle :: Maybe String,          -- ^ @-doctitle@
+  header :: Maybe String,            -- ^ @-header@
+  footer :: Maybe String,            -- ^ @-footer@
+  top :: Maybe String,               -- ^ @-top@
+  bottom :: Maybe String,            -- ^ @-bottom@
+  link :: [String],                  -- ^ @-link@
+  linkoffline :: [(String, String)], -- ^ @-linkoffline@
+  excludedocfilessubdir :: [String], -- ^ @-excludedocfilessubdir@
+  group :: [(String, [String])],     -- ^ @-group@
+  nocomment :: Bool,                 -- ^ @-nocomment@
+  nodeprecated :: Bool,              -- ^ @-nodeprecated@
+  noqualifier :: [String],           -- ^ @-noqualifier@
+  nosince :: Bool,                   -- ^ @-nosince@
+  notimestamp :: Bool,               -- ^ @-notimestamp@
+  nodeprecatedlist :: Bool,          -- ^ @-nodeprecatedlist@
+  notree :: Bool,                    -- ^ @-notree@
+  noindex :: Bool,                   -- ^ @-noindex@
+  nohelp :: Bool,                    -- ^ @-nohelp@
+  nonavbar :: Bool,                  -- ^ @-nonavbar@
+  serialwarn :: Bool,                -- ^ @-serialwarn@
+  tag :: [(String, String, String)], -- ^ @-tag@
+  taglet :: Bool,                    -- ^ @-taglet@
+  tagletpath :: Bool,                -- ^ @-tagletpath@
+  charset :: Maybe String,           -- ^ @-charset@
+  helpfile :: Maybe FilePath,        -- ^ @-helpfile@
+  linksource :: Bool,                -- ^ @-linksource@
+  sourcetab :: Maybe Int,            -- ^ @-sourcetab@
+  keywords :: Bool,                  -- ^ @-keywords@
+  stylesheetfile :: Maybe FilePath,  -- ^ @-stylesheetfile@
+  docencoding :: Maybe String        -- ^ @-docencoding@
+}
+
+-- | A @Javadoc@ with nothing set.
+javadoc :: Javadoc
+javadoc = Javadoc Nothing False False False False False Nothing Nothing [] [] [] [] False [] Nothing [] False Nothing Nothing False [] Nothing False False False False False Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] [] False False [] False False False False False False False False [] False False Nothing Nothing False Nothing False Nothing Nothing
+
+-- | Construct a @Javadoc@.
+javadoc' :: Maybe FilePath
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Maybe String
+            -> Maybe FilePath
+            -> [FilePath]
+            -> [FilePath]
+            -> [String]
+            -> [String]
+            -> Bool
+            -> [FilePath]
+            -> Maybe SourceRelease
+            -> [FilePath]
+            -> Bool
+            -> Maybe String
+            -> Maybe String
+            -> Bool
+            -> [String]
+            -> Maybe FilePath
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Maybe String
+            -> Maybe String
+            -> Maybe String
+            -> Maybe String
+            -> Maybe String
+            -> Maybe String
+            -> [String]
+            -> [(String, String)]
+            -> [String]
+            -> [(String, [String])]
+            -> Bool
+            -> Bool
+            -> [String]
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> Bool
+            -> [(String, String, String)]
+            -> Bool
+            -> Bool
+            -> Maybe String
+            -> Maybe FilePath
+            -> Bool
+            -> Maybe Int
+            -> Bool
+            -> Maybe FilePath
+            -> Maybe String
+            -> Javadoc
+javadoc' = Javadoc
+
+instance Show Javadoc where
+  show (Javadoc overview'
+                public'
+                protected'
+                package'
+                private'
+                help'
+                doclet'
+                docletpath'
+                sourcepath'
+                classpath'
+                exclude'
+                subpackages'
+                breakiterator'
+                bootclasspath'
+                source'
+                extdirs'
+                verbose'
+                locale'
+                encoding'
+                quiet'
+                flags'
+                directory'
+                use'
+                version'
+                author'
+                docfilessubdirs'
+                splitindex'
+                windowtitle'
+                doctitle'
+                header'
+                footer'
+                top'
+                bottom'
+                link'
+                linkoffline'
+                excludedocfilessubdir'
+                group'
+                nocomment'
+                nodeprecated'
+                noqualifier'
+                nosince'
+                notimestamp'
+                nodeprecatedlist'
+                notree'
+                noindex'
+                nohelp'
+                nonavbar'
+                serialwarn'
+                tag'
+                taglet'
+                tagletpath'
+                charset'
+                helpfile'
+                linksource'
+                sourcetab'
+                keywords'
+                stylesheetfile'
+                docencoding') = ["overview" ~~> overview',
+                                 "public" ~~ public',
+                                 "protected" ~~ protected',
+                                 "package" ~~ package',
+                                 "private" ~~ private',
+                                 "help" ~~ help',
+                                 "doclet" ~~> doclet',
+                                 "docletpath" ~~> docletpath',
+                                 "sourcepath" ~: sourcepath',
+                                 "classpath" ~: classpath',
+                                 c exclude',
+                                 c subpackages',
+                                 "breakiterator" ~~ breakiterator',
+                                 "bootclasspath" ~: bootclasspath',
+                                 "source" ~~> source',
+                                 "extdirs" ~: extdirs',
+                                 "verbose" ~~ verbose',
+                                 "locale" ~~> locale',
+                                 "encoding" ~~> encoding',
+                                 "quiet" ~~ quiet',
+                                 intercalate " " $ map ("-J" ++) flags',
+                                 "d" ~~> directory',
+                                 "use" ~~ use',
+                                 "version" ~~ version',
+                                 "author" ~~ author',
+                                 "docfilessubdirs" ~~ docfilessubdirs',
+                                 "splitindex" ~~ splitindex',
+                                 "windowtitle" ~~> windowtitle',
+                                 "doctitle" ~~> doctitle',
+                                 "header" ~~> header',
+                                 "footer" ~~> footer',
+                                 "top" ~~> top',
+                                 "bottom" ~~> bottom',
+                                 "link" `many` link',
+                                 manys (\(x, y) -> x ++ "\" \"" ++ y) "linkoffline" linkoffline',
+                                 intercalate ":" excludedocfilessubdir',
+                                 manys (\(x, y) -> x ++ "\" \"" ++ c y) "group" group',
+                                 "nocomment" ~~ nocomment',
+                                 "nodeprecated" ~~ nodeprecated',
+                                 intercalate ":" noqualifier',
+                                 "nosince" ~~ nosince',
+                                 "notimestamp" ~~ notimestamp',
+                                 "nodeprecatedlist" ~~ nodeprecatedlist',
+                                 "notree" ~~ notree',
+                                 "noindex" ~~ noindex',
+                                 "nohelp" ~~ nohelp',
+                                 "nonavbar" ~~ nonavbar',
+                                 "serialwarn" ~~ serialwarn',
+                                 manys (\(x, y, z) -> c [x, y, z]) "tag" tag',
+                                 "taglet" ~~ taglet',
+                                 "tagletpath" ~~ tagletpath',
+                                 "charset" ~~> charset',
+                                 "helpfile" ~~> helpfile',
+                                 "linksource" ~~ linksource',
+                                 "sourcetab" ~~> sourcetab',
+                                 "keywords" ~~ keywords',
+                                 "stylesheetfile" ~~> stylesheetfile',
+                                 "docencoding" ~~> docencoding'
+                                 ] ^^^ " "
+                                 where
+                                   c = intercalate ":"
+
+instance CompilePaths Javadoc where
+  j =>> ps = show j ++ ' ' : space ps
+
+instance Extensions Javadoc where
+  exts _ = ["java"]
+
+instance OutputDirectory Javadoc where
+  outdir = directory
+
+instance OutputReferenceSet Javadoc where
+  setReference p j = j { classpath = p }
+
+instance OutputReferenceGet Javadoc where
+  getReference = classpath
+
+instance Command Javadoc where
+  command _ = let envs = [
+                            ("JAVA_HOME", (</> "bin" </> "javadoc")),
+                            ("JDK_HOME", (</> "bin" </> "javadoc")),
+                            ("JAVADOC", id)
+                         ]
+              in fromMaybe "javadoc" `fmap` tryEnvs envs
diff --git a/System/Build/OutputDirectory.hs b/System/Build/OutputDirectory.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/OutputDirectory.hs
@@ -0,0 +1,9 @@
+-- | Values that have the potential for an output directory.
+module System.Build.OutputDirectory(
+                                     OutputDirectory,
+                                     outdir,
+                                   ) where
+
+class OutputDirectory o where
+  -- Return the potential output directory for the given value.
+  outdir :: o -> Maybe FilePath
diff --git a/System/Build/OutputReferenceGet.hs b/System/Build/OutputReferenceGet.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/OutputReferenceGet.hs
@@ -0,0 +1,9 @@
+-- | Values that reference a list of file paths.
+module System.Build.OutputReferenceGet(
+                                        OutputReferenceGet,
+                                        getReference
+                                      ) where
+
+class OutputReferenceGet r where
+  -- | Return the file paths referenced by the given value.
+  getReference :: r -> [FilePath]
diff --git a/System/Build/OutputReferenceSet.hs b/System/Build/OutputReferenceSet.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/OutputReferenceSet.hs
@@ -0,0 +1,9 @@
+-- | Values that reference a list of file paths.
+module System.Build.OutputReferenceSet(
+                                        OutputReferenceSet,
+                                        setReference
+                                      ) where
+
+class OutputReferenceSet r where
+  -- | Set the file path list reference of the given value.
+  setReference :: [FilePath] -> r -> r
diff --git a/System/Build/Runner.hs b/System/Build/Runner.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Runner.hs
@@ -0,0 +1,119 @@
+-- | A module for running compilable data types that take a list of file paths to compile.
+module System.Build.Runner(
+                            -- * Runners
+                            Runner,
+                            RunnerExit,
+                            -- * Chaining Runners
+                            (>--),
+                            (>==),
+                            -- * Transforming file paths
+                            pathTransform,
+                            pathTransform',
+                            -- * Running system command
+                            (!!!),
+                            (>->),
+                            (->-),
+                            -- * Chaining References.
+                            (+>>),
+                            (++>>),
+                            (>===>),
+                            (>=>=>)
+                          ) where
+
+import Control.Monad
+import Data.Maybe
+import System.Cmd
+import System.Directory
+import System.Exit
+import System.Build.FilePather
+import System.Build.Extensions
+import System.Build.Command
+import System.Build.CompilePaths
+import System.Build.OutputDirectory
+import System.Build.OutputReferenceGet
+import System.Build.OutputReferenceSet
+
+type Runner e r = r -> [FilePath] -> IO e
+
+type RunnerExit r = Runner ExitCode r
+
+-- | Applies the second value only if the first produces @ExitSuccess@.
+(>--) :: (Monad m) =>
+         m ExitCode ->
+         m ExitCode ->
+         m ExitCode
+f >-- g = do e <- f
+             if e == ExitSuccess
+               then g
+               else return e
+
+-- | Executes the second action only if the first produces @ExitSuccess@.
+(>==) :: (Monad m) =>
+         m ExitCode ->
+         m () ->
+         m ()
+p >== q = do e <- p
+             when (e == ExitSuccess) q
+
+
+-- | Transform the list of file paths before executing the runner.
+pathTransform :: ([FilePath] -> IO [FilePath]) ->
+                 Runner x t ->
+                 Runner x t
+pathTransform k f c p = k p >>= f c
+
+-- | Get all file paths with the given file extension (recursively) and execute the runner on those.
+pathTransform' :: (Extensions e) =>
+                  e ->
+                  Runner x r ->
+                  Runner x r
+pathTransform' = pathTransform . recurse
+  where
+  recurse c p = fmap concat $ find always (constant $ extension ==|| exts' c) `mapM` p
+
+(!!!) :: (Command c, CompilePaths c) =>
+         RunnerExit c
+c !!! z = do s <- command c
+             system (s ++ ' ' : c =>> z)
+
+-- | Create the output target directory then execute the compile result as a system command.
+(>->) :: (OutputDirectory c, Command c, CompilePaths c) =>
+         RunnerExit c
+c >-> z = do mkdirectory (outdir c)
+             c !!! z
+  where
+  mkdirectory = mapM_ (createDirectoryIfMissing True) . maybeToList
+
+-- | A runner that recursively searches the output target for files that match a given extension and compiles them as a system command.
+(->-) :: (OutputDirectory c, Extensions c, CompilePaths c, Command c) =>
+          RunnerExit c
+c ->- p = pathTransform' c (>->) c p
+
+-- | Adds the given file path to the reference target of the given value.
+(+>>) :: (OutputReferenceGet r, OutputReferenceSet r) =>
+         FilePath -- ^ The file path to add.
+         -> r     -- ^ The value to add the given file path to.
+         -> r     -- ^ The value with the given file path added.
+v +>> k = setReference (v : getReference k) k
+
+-- | Adds the given file paths to the reference target of the given value.
+(++>>) :: (OutputReferenceGet r, OutputReferenceSet r) =>
+          [FilePath] -- ^ The file paths to add.
+          -> r       -- ^ The value to add the given file paths to.
+          -> r       -- ^ The value with the given file paths added.
+v ++>> k = setReference (v ++ getReference k) k
+
+-- | Adds the (potential) output target of the given value to the output target of the given value.
+(>===>) :: (OutputDirectory o, OutputReferenceGet r, OutputReferenceSet r) =>
+           o    -- ^ The value with an output target value to add.
+           -> r -- ^ The value to add the output target to.
+           -> r -- ^ The value after the output target has been added.
+v >===> w = case outdir v of Nothing -> w
+                             Just y -> y +>> w
+
+-- | Adds the (potential) output target and output references of the given value to the output target of the given value.
+(>=>=>) :: (OutputDirectory o, OutputReferenceGet o, OutputReferenceGet r, OutputReferenceSet r) =>
+           o    -- ^ The value with an output target and output references to add.
+           -> r -- ^ The value to add the output target and output references to.
+           -> r -- ^ The value after the output target has been added.
+v >=>=> w = v >===> (getReference v ++>> w)
diff --git a/System/Build/Scala/Access.hs b/System/Build/Scala/Access.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Scala/Access.hs
@@ -0,0 +1,15 @@
+-- | A module that represents that access levels available to @scaladoc@.
+module System.Build.Scala.Access(
+                                  Access(..)
+                                ) where
+
+-- | Show only public, protected/public (default) or all classes and members (public,protected,private)
+data Access = Public      -- ^ @public@
+              | Protected -- ^ @protected@
+              | Private   -- ^ @private@
+              deriving Eq
+
+instance Show Access where
+  show Public = "public"
+  show Protected = "protected"
+  show Private = "private"
diff --git a/System/Build/Scala/Debug.hs b/System/Build/Scala/Debug.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Scala/Debug.hs
@@ -0,0 +1,19 @@
+-- | A module that represents the debug levels to @scalac@ and @scaladoc@.
+module System.Build.Scala.Debug(
+                                 Debug(..)
+                               ) where
+
+-- | Specify level of generated debugging info (none,source,line,vars,notailcalls)
+data Debug = None          -- ^ @none@
+             | Source      -- ^ @source@
+             | Line        -- ^ @line@
+             | Vars        -- ^ @vars@
+             | NoTailCalls -- ^ @notailcalls@
+             deriving Eq
+
+instance Show Debug where
+  show None = "none"
+  show Source = "source"
+  show Line = "line"
+  show Vars = "vars"
+  show NoTailCalls = "notailcalls"
diff --git a/System/Build/Scala/Scalac.hs b/System/Build/Scala/Scalac.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Scala/Scalac.hs
@@ -0,0 +1,210 @@
+-- | A module for compiling Scala source files using @scalac@.
+module System.Build.Scala.Scalac(
+                                  Fsc,
+                                  Scalac,
+                                  -- * @Scalac@ members
+                                  debug,
+                                  nowarn,
+                                  verbose,
+                                  deprecation,
+                                  unchecked,
+                                  classpath,
+                                  sourcepath,
+                                  bootclasspath,
+                                  extdirs,
+                                  directory,
+                                  encoding,
+                                  target,
+                                  print,
+                                  optimise,
+                                  explaintypes,
+                                  uniqid,
+                                  version,
+                                  help,
+                                  (?),
+                                  etc,
+                                  -- * @Scalac@ values
+                                  scalac,
+                                  scalac',
+                                  kscalac,
+                                  fscalac,
+                                  -- * @Fsc@ members
+                                  reset,
+                                  shutdown,
+                                  server,
+                                  flags,
+                                  -- * @Fsc@ values
+                                  fsc
+                                ) where
+
+import Prelude hiding (print)
+import System.Build.Args
+import System.Build.Scala.Debug
+import System.Build.Scala.Target
+import System.Build.CompilePaths
+import System.Build.Extensions
+import System.Build.OutputDirectory
+import System.Build.OutputReferenceSet
+import System.Build.OutputReferenceGet
+import System.Build.Command
+import Control.Monad
+import Data.List
+import Data.Maybe
+import System.FilePath
+
+-- | Scalac is the compiler for Scala source files.
+data Scalac = Scalac {
+  debug :: Maybe Debug,        -- ^ @-g@
+  nowarn :: Bool,              -- ^ @-nowarn@
+  verbose :: Bool,             -- ^ @-verbose@
+  deprecation :: Bool,         -- ^ @-deprecation@
+  unchecked :: Bool,           -- ^ @-unchecked@
+  classpath :: [FilePath],     -- ^ @-classpath@
+  sourcepath :: [FilePath],    -- ^ @-sourcepath@
+  bootclasspath :: [FilePath], -- ^ @-bootclasspath@
+  extdirs :: [FilePath],       -- ^ @-extdirs@
+  directory :: Maybe FilePath, -- ^ @-d@
+  encoding :: Maybe String,    -- ^ @-encoding@
+  target :: Maybe Target,      -- ^ @-target@
+  print :: Bool,               -- ^ @-print@
+  optimise :: Bool,            -- ^ @-optimise@
+  explaintypes :: Bool,        -- ^ @-explaintypes@
+  uniqid :: Bool,              -- ^ @-uniqid@
+  version :: Bool,             -- ^ @-version@
+  help :: Bool,                -- ^ @-help@
+  (?) :: Maybe FilePath,       -- ^ @\@@
+  etc :: Maybe String
+}
+
+-- | A @Scalac@ with nothing set.
+scalac :: Scalac
+scalac = Scalac Nothing False False False False [] [] [] [] Nothing Nothing Nothing False False False False False False Nothing Nothing
+
+-- | Construct a @Scalac@.
+scalac' :: Maybe System.Build.Scala.Debug.Debug
+           -> Bool
+           -> Bool
+           -> Bool
+           -> Bool
+           -> [FilePath]
+           -> [FilePath]
+           -> [FilePath]
+           -> [FilePath]
+           -> Maybe FilePath
+           -> Maybe String
+           -> Maybe Target
+           -> Bool
+           -> Bool
+           -> Bool
+           -> Bool
+           -> Bool
+           -> Bool
+           -> Maybe FilePath
+           -> Maybe String
+           -> Scalac
+scalac' = Scalac
+
+-- | Convert the given scalac to a list of command line options which may be used by other scala tools.
+kscalac :: Scalac -> [String]
+kscalac (Scalac debug'
+                 nowarn'
+                 verbose'
+                 deprecation'
+                 unchecked'
+                 classpath'
+                 sourcepath'
+                 bootclasspath'
+                 extdirs'
+                 directory'
+                 encoding'
+                 target'
+                 print'
+                 optimise'
+                 explaintypes'
+                 uniqid'
+                 version'
+                 help'
+                 script'
+                 etc') = ["g" -~> debug',
+                         "nowarn" ~~ nowarn',
+                         "verbose" ~~ verbose',
+                         "deprecation" ~~ deprecation',
+                         "unchecked" ~~ unchecked',
+                         "classpath" ~: classpath',
+                         "sourcepath" ~: sourcepath',
+                         "bootclasspath" ~: bootclasspath',
+                         "extdirs" ~: extdirs',
+                         "d" ~~> directory',
+                         "encoding" ~~> encoding',
+                         "target" -~> target',
+                         "print" ~~ print',
+                         "optimise" ~~ optimise',
+                         "explaintypes" ~~ explaintypes',
+                         "uniqid" ~~ uniqid',
+                         "version" ~~ version',
+                         "help" ~~ help',
+                         (:) '@' ~? script',
+                         fromMaybe [] etc']
+
+instance Show Scalac where
+  show s = kscalac s ^^^ " "
+
+instance CompilePaths Scalac where
+  j =>> ps = show j ++ ' ' : space ps
+
+instance Extensions Scalac where
+  exts _ = ["java", "scala"]
+
+instance OutputDirectory Scalac where
+  outdir = directory
+
+instance OutputReferenceSet Scalac where
+  setReference p j = j { classpath = p }
+
+instance OutputReferenceGet Scalac where
+  getReference = classpath
+
+instance Command Scalac where
+  command _ = let envs = [
+                            ("SCALA_HOME", (</> "bin" </> "scalac")),
+                            ("SCALAC", id)
+                         ]
+              in fromMaybe "scalac" `fmap` tryEnvs envs
+
+-- | The Scala fast compiler (@fsc@).
+data Fsc = Fsc {
+  fscalac :: Scalac,                -- ^ The scalac options to use.
+  reset :: Bool,                    -- ^ @-reset@
+  shutdown :: Bool,                 -- ^ @-shutdown@
+  server :: Maybe (String, String), -- ^ @-server@
+  flags :: [String]                 -- ^ @-flags@
+}
+
+instance Show Fsc where
+  show (Fsc fscalac' reset' shutdown' server' flags') = (kscalac fscalac' ++ ["reset" ~~ reset', "shutdown" ~~ shutdown', maybe [] (uncurry (++)) server', intercalate " " (fmap ("-J" ++) flags')]) ^^^ " "
+
+instance CompilePaths Fsc where
+  j =>> ps = show j ++ ' ' : space ps
+
+instance Extensions Fsc where
+  exts _ = ["java", "scala"]
+
+instance OutputDirectory Fsc where
+  outdir = directory . fscalac
+
+instance OutputReferenceSet Fsc where
+  setReference p j = let s = fscalac j in j { fscalac = setReference p s }
+
+instance OutputReferenceGet Fsc where
+  getReference = getReference . fscalac
+
+instance Command Fsc where
+  command _ = let envs = [
+                            ("SCALA_HOME", (</> "bin" </> "fsc")),
+                            ("FSC", id)
+                         ]
+              in fromMaybe "fsc" `fmap` tryEnvs envs
+
+-- | A @Fsc@ with nothing set.
+fsc :: Fsc
+fsc = Fsc scalac False False Nothing []
diff --git a/System/Build/Scala/Scaladoc.hs b/System/Build/Scala/Scaladoc.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Scala/Scaladoc.hs
@@ -0,0 +1,193 @@
+-- | A module for documenting Scala source files using @scaladoc@.
+module System.Build.Scala.Scaladoc(
+                                    Scaladoc,
+                                    -- * @Scaladoc@ members
+                                    debug,
+                                    nowarn,
+                                    verbose,
+                                    deprecation,
+                                    unchecked,
+                                    classpath,
+                                    sourcepath,
+                                    bootclasspath,
+                                    extdirs,
+                                    directory,
+                                    encoding,
+                                    target,
+                                    print,
+                                    optimise,
+                                    explaintypes,
+                                    uniqid,
+                                    version,
+                                    help,
+                                    (?),
+                                    access,
+                                    bottom,
+                                    charset,
+                                    doctitle,
+                                    footer,
+                                    header,
+                                    linksource,
+                                    nocomment,
+                                    stylesheetfile,
+                                    top,
+                                    windowtitle,
+                                    etc,
+                                    -- * @Scaladoc@ values
+                                    scaladoc,
+                                    scaladoc'
+                                  ) where
+
+import Data.Maybe
+import Prelude hiding (print)
+import System.FilePath
+import System.Build.Args
+import System.Build.CompilePaths
+import System.Build.Extensions
+import System.Build.OutputDirectory
+import System.Build.OutputReferenceSet
+import System.Build.OutputReferenceGet
+import System.Build.Command
+import System.Build.Scala.Target
+import System.Build.Scala.Debug
+import System.Build.Scala.Access
+import System.Build.Scala.Scalac (kscalac, scalac')
+
+-- | Javadoc is the compiler for Scala API documentation.
+data Scaladoc = Scaladoc {
+  debug :: Maybe Debug,           -- ^ @-g@
+  nowarn :: Bool,                 -- ^ @-nowarn@
+  verbose :: Bool,                -- ^ @-verbose@
+  deprecation :: Bool,            -- ^ @-deprecation@
+  unchecked :: Bool,              -- ^ @-unchecked@
+  classpath :: [FilePath],        -- ^ @-classpath@
+  sourcepath :: [FilePath],       -- ^ @-sourcepath@
+  bootclasspath :: [FilePath],    -- ^ @-bootclasspath@
+  extdirs :: [FilePath],          -- ^ @-extdirs@
+  directory :: Maybe FilePath,    -- ^ @-d@
+  encoding :: Maybe String,       -- ^ @-encoding@
+  target :: Maybe Target,         -- ^ @-target@
+  print :: Bool,                  -- ^ @-print@
+  optimise :: Bool,               -- ^ @-optimise@
+  explaintypes :: Bool,           -- ^ @-explaintypes@
+  uniqid :: Bool,                 -- ^ @-uniqid@
+  version :: Bool,                -- ^ @-version@
+  help :: Bool,                   -- ^ @-help@
+  (?) :: Maybe FilePath,          -- ^ @\@@
+  access :: Maybe Access,         -- ^ @-access@
+  bottom :: Maybe String,         -- ^ @-bottom@
+  charset :: Maybe String,        -- ^ @-charset@
+  doctitle :: Maybe String,       -- ^ @-doctitle@
+  footer :: Maybe String,         -- ^ @-footer@
+  header :: Maybe String,         -- ^ @-header@
+  linksource :: Bool,             -- ^ @-linksource@
+  nocomment :: Bool,              -- ^ @-nocomment@
+  stylesheetfile :: Maybe String, -- ^ @-stylesheetfile@
+  top :: Maybe String,            -- ^ @-top@
+  windowtitle :: Maybe String,    -- ^ @-windowtitle@
+  etc :: Maybe String
+}
+
+-- | A @Scaladoc@ with nothing set.
+scaladoc :: Scaladoc
+scaladoc = Scaladoc Nothing False False False False [] [] [] [] Nothing Nothing Nothing False False False False False False Nothing Nothing Nothing Nothing Nothing Nothing Nothing False False Nothing Nothing Nothing Nothing
+
+-- | Construct a @Scaladoc@.
+scaladoc' :: Maybe Debug
+             -> Bool
+             -> Bool
+              -> Bool
+             -> Bool
+             -> [FilePath]
+             -> [FilePath]
+             -> [FilePath]
+             -> [FilePath]
+             -> Maybe FilePath
+             -> Maybe String
+             -> Maybe Target
+             -> Bool
+             -> Bool
+             -> Bool
+             -> Bool
+             -> Bool
+             -> Bool
+             -> Maybe FilePath
+             -> Maybe Access
+             -> Maybe String
+             -> Maybe String
+             -> Maybe String
+             -> Maybe String
+             -> Maybe String
+             -> Bool
+             -> Bool
+             -> Maybe String
+             -> Maybe String
+             -> Maybe String
+             -> Maybe String
+             -> Scaladoc
+scaladoc' = Scaladoc
+
+instance Show Scaladoc where
+  show (Scaladoc debug'
+                 nowarn'
+                 verbose'
+                 deprecation'
+                 unchecked'
+                 classpath'
+                 sourcepath'
+                 bootclasspath'
+                 extdirs'
+                 directory'
+                 encoding'
+                 target'
+                 print'
+                 optimise'
+                 explaintypes'
+                 uniqid'
+                 version'
+                 help'
+                 script'
+                 access'
+                 bottom'
+                 charset'
+                 doctitle'
+                 footer'
+                 header'
+                 linksource'
+                 nocomment'
+                 stylesheetfile'
+                 top'
+                 windowtitle'
+                 etc') = (kscalac (scalac' debug' nowarn' verbose' deprecation' unchecked' classpath' sourcepath' bootclasspath' extdirs' directory' encoding' target' print' optimise' explaintypes' uniqid' version' help' script' etc') ++ ["access" -~> access',
+                                      "bottom" ~~> bottom',
+                                      "charset" ~~> charset',
+                                      "doctitle" ~~> doctitle',
+                                      "footer" ~~> footer',
+                                      "header" ~~> header',
+                                      "linksource" ~~ linksource',
+                                      "nocomment" ~~ nocomment',
+                                      "stylesheetfile" ~~> stylesheetfile',
+                                      "top" ~~> top',
+                                      "windowtitle" ~~> windowtitle']) ^^^ " "
+
+instance CompilePaths Scaladoc where
+  j =>> ps = show j ++ ' ' : space ps
+
+instance Extensions Scaladoc where
+  exts _ = ["scala"]
+
+instance OutputDirectory Scaladoc where
+  outdir = directory
+
+instance OutputReferenceSet Scaladoc where
+  setReference p j = j { classpath = p }
+
+instance OutputReferenceGet Scaladoc where
+  getReference = classpath
+
+instance Command Scaladoc where
+  command _ = let envs = [
+                           ("SCALA_HOME", (</> "bin" </> "scaladoc")),
+                           ("SCALADOC", id)
+                         ]
+              in fromMaybe "scaladoc" `fmap` tryEnvs envs
diff --git a/System/Build/Scala/Target.hs b/System/Build/Scala/Target.hs
new file mode 100644
--- /dev/null
+++ b/System/Build/Scala/Target.hs
@@ -0,0 +1,15 @@
+-- | A module that represents the target levels to @scalac@ and @scaladoc@.
+module System.Build.Scala.Target(
+                                  Target(..)
+                                ) where
+
+-- | Specify for which target object files should be built (jvm-1.5,jvm-1.4,msil)
+data Target = JVM15   -- ^ @jvm-1.5@
+              | JVM14 -- ^ @jvm-1.4@
+              | MSIL   -- ^ @msil@
+  deriving Eq
+
+instance Show Target where
+  show JVM15 = "jvm-1.5"
+  show JVM14 = "jvm-1.4"
+  show MSIL = "msil"
