diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2009 Tony Morris
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/Lastik.cabal b/Lastik.cabal
new file mode 100644
--- /dev/null
+++ b/Lastik.cabal
@@ -0,0 +1,37 @@
+Name:               Lastik
+Version:            0.1
+License:            BSD3
+License-File:       LICENSE
+Author:             Tony Morris <tmorris@tmorris.net>
+Maintainer:         Tony Morris
+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#.
+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, FileManip, zip-archive
+  else
+    Build-Depends: base < 3, filepath, process, FileManip, zip-archive
+
+  GHC-Options:    -Wall
+  Exposed-Modules:
+          Lastik.Compile,
+          Lastik.Directory,
+          Lastik.Extension,
+          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
diff --git a/Lastik/Compile.hs b/Lastik/Compile.hs
new file mode 100644
--- /dev/null
+++ b/Lastik/Compile.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE FlexibleInstances #-}
+
+-- | A module for representing data types that can be compiled by taking a list of files.
+module Lastik.Compile (
+                       Compile,
+                       compile
+                      ) where
+
+import Control.Monad
+import Data.List
+import System.Directory
+import System.Cmd
+import System.Exit
+
+-- | 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
diff --git a/Lastik/Directory.hs b/Lastik/Directory.hs
new file mode 100644
--- /dev/null
+++ b/Lastik/Directory.hs
@@ -0,0 +1,89 @@
+-- | A module for performing operations on directories.
+module Lastik.Directory(
+                        chdir,
+                        archiveDirectories,
+                        writeArchive,
+                        copyDir,
+                        dropRoot,
+                        dropRoot',
+                        mkdir,
+                        rmdir
+                        ) where
+
+import System.Directory
+import System.FilePath
+import System.FilePath.Find
+import Codec.Archive.Zip
+import qualified Data.ByteString.Lazy as B
+import Control.Monad
+import Control.Exception
+
+-- | 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 directory to change to and contents of that directory to archive.
+                      -> RecursionPredicate  -- ^ 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 directory to change to and contents of that directory to archive.
+                -> RecursionPredicate  -- ^ 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)
+
+-- | Copy the contents of a directory to another, perhaps trimming parent directories.
+copyDir :: RecursionPredicate -- ^ 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Extension.hs
@@ -0,0 +1,21 @@
+{-# 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/Java/Javac.hs b/Lastik/Java/Javac.hs
new file mode 100644
--- /dev/null
+++ b/Lastik/Java/Javac.hs
@@ -0,0 +1,222 @@
+-- | 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Java/Javadoc.hs
@@ -0,0 +1,344 @@
+-- | 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Output.hs
@@ -0,0 +1,90 @@
+{-# 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 System.FilePath.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
new file mode 100644
--- /dev/null
+++ b/Lastik/Runner.hs
@@ -0,0 +1,112 @@
+-- | 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 System.FilePath.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 (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
new file mode 100644
--- /dev/null
+++ b/Lastik/Scala/Access.hs
@@ -0,0 +1,15 @@
+-- | 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Scala/Debug.hs
@@ -0,0 +1,19 @@
+-- | 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Scala/Scalac.hs
@@ -0,0 +1,183 @@
+-- | 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Scala/Scaladoc.hs
@@ -0,0 +1,177 @@
+-- | 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Scala/Target.hs
@@ -0,0 +1,15 @@
+-- | 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
new file mode 100644
--- /dev/null
+++ b/Lastik/Util.hs
@@ -0,0 +1,134 @@
+module Lastik.Util(
+                   (>>>>),
+                   (>>>>>),
+                   quote,
+                   (>===<),
+                   (~~),
+                   (~??),
+                   (~?),
+                   param,
+                   many,
+                   manys,
+                   (~~~~>),
+                   (~~~>),
+                   (~~>),
+                   (-~>),
+                   (^^^),
+                   space,
+                   space',
+                   uncons
+                  ) 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@.
+(>>>>) :: (Applicative f) => f ExitCode -> f ExitCode -> f ExitCode
+(>>>>) = let ExitSuccess `k` q = q
+             p `k` _= p
+         in liftA2 k
+
+-- | 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
+
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+main = defaultMain
+
