diff --git a/AUTHORS b/AUTHORS
new file mode 100644
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,1 @@
+Bit Connor <mutantlemon@gmail.com>
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,182 @@
+hdevtools
+=========
+
+Persistent GHC powered background server for FAST Haskell development tools
+
+About
+-----
+
+`hdevtools` is a backend for text editor plugins, to allow for things such as
+syntax and type checking of Haskell code, and retrieving type information, all
+directly from within your text editor.
+
+The advantage that `hdevtools` has over competitors, is that it runs silently
+in a persistent background process, and therefore is able to keeps all of your
+Haskell modules and dependent libraries loaded in memory. This way, when you
+change only a single source file, only it needs to be reloaded and rechecked,
+instead of having to reload everything.
+
+This makes `hdevtools` very fast for checking syntax and type errors (runs just
+as fast as the `:reload` command in GHCi).
+
+In fact, syntax and type checking is so fast, that you can safely enable auto
+checking on every save. Even for huge projects, checking is nearly instant.
+
+Once you start using `hdevtools` and you get used to having your errors shown
+to you instantly (without having to switch back and forth between GHCi and your
+editor), and shown directly on your code, in your editor (without having to
+wait forever for GHC to run) you will wonder how you ever lived without it.
+
+In addition to checking Haskell source code for errors, `hdevtools` has tools
+for getting info about identifiers, and getting type information for snippets
+of code.
+
+Text Editor Integration
+-----------------------
+
+`hdevtools` is designed to be integrated into text editors. The list of current
+editor plugins that supply this integration is below.
+
+But before you do anything, you must first install `hdevtools` itself. The
+easiest way is from [Hackage][1] via cabal install:
+
+    $ cabal install hdevtools
+
+Then you should install one or more of the following editor plugins:
+
+### Vim - [Syntastic][2] ###
+
+[Syntastic][2] is a popular syntax checking plugin for Vim, and is the
+recommended Vim integration of `hdevtools` syntax and type checking. Recent
+versions of Syntastic(since Sep. 2012) have builtin support for `hdevtools`.
+
+Simply install `hdevtools` (as above) and [Syntastic][2], and it will
+automatically check your Haskell files.
+
+[Syntastic][2] will respect the `g:hdevtools_options` variable (the same one as
+used by [vim-hdevtools][3], see below). See the section "Specifying GHC
+Options" below for details how to use it.
+
+### Vim - [vim-hdevtools][3] ###
+
+In addition to Syntastic, it is recommended that you also use
+[`vim-hdevtools`][3] for additional functionality.
+
+[`vim-hdevtools`][3] offers integration with the rest of the `hdevtools` tools,
+including retrieving info about the identifier under the cursor, and getting
+the type of the code under the cursor. Refer to its documentation for more
+details.
+
+### Emacs ###
+
+I encourage the community to develop integration plugins for Emacs and other
+editors. In the mean time, please see the manual integration information below.
+
+### Manual Editor Integration for any Editor ###
+
+Most editors allow you to run a `make` command, and will then parse the output
+for errors and show line numbers, allowing you to jump between errors.
+
+The `hdevtools check` command is suitable for such usage.
+
+For example, in Vim something like this will work:
+
+    :let &makeprg='hdevtools check %'
+
+(Vim will replace the `%` character with the name of the current file). Then
+you can run
+
+    :make
+
+And Vim will invoke `hdevtools` to check the current file for errors, and then
+show a list of them and allow jumping to them.
+
+See the "Command Line Usage" section below for more information.
+
+Command Line Usage
+------------------
+
+Note: When using one of the above editor plugins, you don't really need to know
+this.
+
+### Available Commands and Help ###
+
+For the list of commands available, run:
+
+    $ hdevtools --help
+
+To get help for a specific command, run:
+
+    $ hdevtools [COMMAND] --help
+
+For example:
+
+    $ hdevtools check --help
+
+### The `hdevtools` background process ###
+
+The first time `hdevtools` runs a command, it will spawn a background process
+that will remain running forever. You can check the status of this background
+process by running:
+
+    $ hdevtools --status
+
+You can shutdown the background process by running:
+
+    $ hdevtools --stop-server
+
+Communication with the background process is done through a unix socket file.
+The default name is `.hdevtools.sock`, in the current directory. This allows
+you to use `hdevtools` with multiple projects simultaneously, without the
+background processes getting in the way of each other.
+
+You can use a different socket file name with the `--socket` option, which
+should be used for each invocation of `hdevtools`. Remember that when telling
+`hdevtools` to check a Haskell file, paths are relative to the path of the
+background process, not your current directory. This can cause problems, and
+therefore it is recommended that you leave the socket file as the default, and
+always run `hdevtools` from the same directory.
+
+### Specifying GHC Options ###
+
+For most non-trivial projects, you will need to tell `hdevtools` about
+additional GHC options that your project requires.
+
+All `hdevtools` commands accept a `-g` flag for this purpose.
+
+For example:
+
+* Your project source code is in the directory `src`
+* You want to use the GHC option `-Wall`
+* You want to hide the package `transformers` to prevent conflicts
+
+Invoke `hdevtools` with something like this:
+
+    $ hdevtools check -g -isrc -g -Wall -g -hide-package -g transformers Foo.hs
+
+Notice that a `-g` flag is inserted before each GHC option. Don't try to string
+multiple GHC options together after a single `-g` flag:
+
+This won't work:
+
+    $ hdevtools check -g '-hide-package transformers' Foo.hs
+
+The Vim plugins allow setting GHC options in the `g:hdevtools_options`
+variable.  For example, for the above project, put the following in your
+`.vimrc`:
+
+    let g:hdevtools_options = '-g -isrc -g -Wall -g -hide-package -g transformers'
+
+In general, you will need to pass to `hdevtools` the same GHC options that you
+would pass to GHCi.
+
+Credits
+-------
+
+`hdevtools` was inspired by [ghcmod][4], but has the advantage that due to its
+client-server architecture it is much faster.
+
+[1]: http://hackage.haskell.org/package/hdevtools
+[2]: https://github.com/scrooloose/syntastic
+[3]: https://github.com/bitc/vim-hdevtools
+[4]: http://www.mew.org/~kazu/proj/ghc-mod/en/
diff --git a/hdevtools.cabal b/hdevtools.cabal
--- a/hdevtools.cabal
+++ b/hdevtools.cabal
@@ -1,5 +1,5 @@
 name:                hdevtools
-version:             0.1.0.4
+version:             0.1.0.5
 synopsis:            Persistent GHC powered background server for FAST haskell development tools
 description:
     'hdevtools' is a backend for text editor plugins, to allow for things such as
@@ -60,7 +60,7 @@
   build-depends:       base == 4.*,
                        cmdargs,
                        directory,
-                       ghc,
+                       ghc >= 7.2,
                        ghc-paths,
                        syb,
                        network,
diff --git a/src/CommandArgs.hs b/src/CommandArgs.hs
--- a/src/CommandArgs.hs
+++ b/src/CommandArgs.hs
@@ -8,6 +8,8 @@
 
 import System.Console.CmdArgs.Implicit
 import System.Environment (getProgName)
+import System.Info (arch, os)
+import qualified Config
 
 #ifdef CABAL
 import Data.Version (showVersion)
@@ -22,6 +24,13 @@
     "unknown-version (not built with cabal)"
 #endif
 
+fullVersion :: String
+fullVersion =
+    concat
+        [ programVersion
+        , " (ghc-", Config.cProjectVersion, "-", arch, "-", os, ")"
+        ]
+
 data HDevTools
     = Admin
         { socket :: Maybe FilePath
@@ -35,6 +44,11 @@
         , ghcOpts :: [String]
         , file :: String
         }
+    | ModuleFile
+        { socket :: Maybe FilePath
+        , ghcOpts :: [String]
+        , module_ :: String
+        }
     | Info
         { socket :: Maybe FilePath
         , ghcOpts :: [String]
@@ -66,6 +80,13 @@
     , file = ""
     }
 
+dummyModuleFile :: HDevTools
+dummyModuleFile = ModuleFile
+    { socket = Nothing
+    , ghcOpts = []
+    , module_ = ""
+    }
+
 dummyInfo :: HDevTools
 dummyInfo = Info
     { socket = Nothing
@@ -99,6 +120,13 @@
     , file     := def += typFile      += argPos 0 += opt ""
     ] += help "Check a haskell source file for errors and warnings"
 
+moduleFile :: Annotate Ann
+moduleFile = record dummyModuleFile
+    [ socket   := def += typFile += help "socket file to use"
+    , ghcOpts  := def += typ "OPTION" += help "ghc options"
+    , module_  := def += typ "MODULE" += argPos 0
+    ] += help "Get the haskell source file corresponding to a module name"
+
 info :: Annotate Ann
 info = record dummyInfo
     [ socket     := def += typFile += help "socket file to use"
@@ -117,11 +145,11 @@
     ] += help "Get the type of the expression at the specified line and column"
 
 full :: String -> Annotate Ann
-full progName = modes_ [admin += auto, check, info, type_]
+full progName = modes_ [admin += auto, check, moduleFile, info, type_]
         += helpArg [name "h", groupname "Help"]
         += versionArg [groupname "Help"]
         += program progName
-        += summary (progName ++ ": " ++ programVersion)
+        += summary (progName ++ ": " ++ fullVersion)
 
 loadHDevTools :: IO HDevTools
 loadHDevTools = do
diff --git a/src/CommandLoop.hs b/src/CommandLoop.hs
--- a/src/CommandLoop.hs
+++ b/src/CommandLoop.hs
@@ -6,6 +6,7 @@
 
 import Control.Monad (when)
 import Data.IORef
+import Data.List (find)
 import MonadUtils (MonadIO, liftIO)
 import System.Exit (ExitCode(ExitFailure, ExitSuccess))
 import qualified ErrUtils
@@ -109,6 +110,29 @@
     liftIO $ case flag of
         GHC.Succeeded -> clientSend (ClientExit ExitSuccess)
         GHC.Failed -> clientSend (ClientExit (ExitFailure 1))
+runCommand _ clientSend (CmdModuleFile moduleName) = do
+    moduleGraph <- GHC.getModuleGraph
+    case find (moduleSummaryMatchesModuleName moduleName) moduleGraph of
+        Nothing ->
+            liftIO $ mapM_ clientSend
+                [ ClientStderr "Module not found"
+                , ClientExit (ExitFailure 1)
+                ]
+        Just modSummary ->
+            case GHC.ml_hs_file (GHC.ms_location modSummary) of
+                Nothing ->
+                    liftIO $ mapM_ clientSend
+                        [ ClientStderr "Module does not have a source file"
+                        , ClientExit (ExitFailure 1)
+                        ]
+                Just file ->
+                    liftIO $ mapM_ clientSend
+                        [ ClientStdout file
+                        , ClientExit ExitSuccess
+                        ]
+    where
+    moduleSummaryMatchesModuleName modName modSummary =
+        modName == (GHC.moduleNameString . GHC.moduleName . GHC.ms_mod) modSummary
 runCommand state clientSend (CmdInfo file identifier) = do
     result <- withWarnings state False $
         getIdentifierInfo file identifier
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -23,6 +23,7 @@
     case args of
         Admin {} -> doAdmin sock args
         Check {} -> doCheck sock args
+        ModuleFile {} -> doModuleFile sock args
         Info {} -> doInfo sock args
         Type {} -> doType sock args
 
@@ -39,6 +40,10 @@
         progName <- getProgName
         hPutStrLn stderr "You must provide a command. See:"
         hPutStrLn stderr $ progName ++ " --help"
+
+doModuleFile :: FilePath -> HDevTools -> IO ()
+doModuleFile sock args =
+    serverCommand sock (CmdModuleFile (module_ args)) (ghcOpts args)
 
 doFileCommand :: String -> (HDevTools -> Command) -> FilePath -> HDevTools -> IO ()
 doFileCommand cmdName cmd sock args
diff --git a/src/Types.hs b/src/Types.hs
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -21,6 +21,7 @@
 
 data Command
     = CmdCheck FilePath
+    | CmdModuleFile String
     | CmdInfo FilePath String
     | CmdType FilePath (Int, Int)
     deriving (Read, Show)
diff --git a/test_all_hsenv.sh b/test_all_hsenv.sh
new file mode 100644
--- /dev/null
+++ b/test_all_hsenv.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+./test_hsenv.sh `echo .hsenv_* | sed -e 's/.hsenv_//g'`
diff --git a/test_hsenv.sh b/test_hsenv.sh
new file mode 100644
--- /dev/null
+++ b/test_hsenv.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -e
+
+if [ $# -lt 1 ]
+then
+	echo "Usage:"
+	echo "$0 <hsenv_name> [<hsenv_name2> ...]"
+	exit 2
+fi
+
+for i in $*
+do
+	source .hsenv_$i/bin/activate
+	cabal build
+	export HDEVTOOLS=./dist_$i/build/hdevtools/hdevtools
+	./tests/test_runner.sh
+	deactivate_hsenv
+done
+
+echo
+echo 'All Tests Passed in:' $*
diff --git a/tests/Child.hs b/tests/Child.hs
new file mode 100644
--- /dev/null
+++ b/tests/Child.hs
@@ -0,0 +1,6 @@
+module Child where
+
+import Parent
+
+child :: String
+child = "child of " ++ parent
diff --git a/tests/Parent.hs b/tests/Parent.hs
new file mode 100644
--- /dev/null
+++ b/tests/Parent.hs
@@ -0,0 +1,4 @@
+module Parent where
+
+parent :: String
+parent = "parent"
diff --git a/tests/SampleError.hs b/tests/SampleError.hs
new file mode 100644
--- /dev/null
+++ b/tests/SampleError.hs
@@ -0,0 +1,9 @@
+-- Sample Module used for testing
+
+-- This module should cause a compilation error:
+--
+-- Sample2.hs:9:1: parse error (possibly incorrect indentation)
+
+module SampleError where
+
+a = foo
diff --git a/tests/Simple.hs b/tests/Simple.hs
new file mode 100644
--- /dev/null
+++ b/tests/Simple.hs
@@ -0,0 +1,7 @@
+-- Sample Module used for testing
+
+-- This module contains no errors or warnings
+module Sample1 where
+
+increment :: Int -> Int
+increment x = x + 1
diff --git a/tests/test_module_file.sh b/tests/test_module_file.sh
new file mode 100644
--- /dev/null
+++ b/tests/test_module_file.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+SOCK=`mktemp -u`
+
+$HDEVTOOLS check --socket=$SOCK Child.hs
+
+PARENT=`$HDEVTOOLS modulefile --socket=$SOCK Parent`
+
+[ "$PARENT" = "./Parent.hs" ]
+
+$HDEVTOOLS --socket=$SOCK --stop-server
diff --git a/tests/test_runner.sh b/tests/test_runner.sh
new file mode 100644
--- /dev/null
+++ b/tests/test_runner.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+set -e
+
+ALL_TESTS="\
+	test_start_stop.sh \
+	test_simple_check.sh \
+	test_sample_error.sh \
+	test_module_file.sh \
+	"
+
+if [ ! $HDEVTOOLS ]
+then
+	echo 'You must set the HDEVTOOLS environment variable to the path of the hdevtools binary'
+	exit 1
+fi
+
+case "$HDEVTOOLS" in
+	*/*)
+		# Convert relative path to absolute:
+		export HDEVTOOLS=`pwd`/$HDEVTOOLS
+esac
+
+echo $HDEVTOOLS
+
+if [ $# -ne 0 ]
+then
+	TESTS=$*
+else
+	TESTS=$ALL_TESTS
+	echo 'Running All Tests'
+fi
+
+echo '------------------------------------------------------------------------'
+
+cd `dirname $0`
+
+ERRORS=0
+for i in $TESTS
+do
+	echo $i
+	echo
+	if sh $i
+	then
+		echo 'Test OK'
+	else
+		echo 'Test FAILED'
+		ERRORS=`expr $ERRORS + 1`
+	fi
+	echo '------------------------------------------------------------------------'
+done
+
+if [ $ERRORS = 0 ]
+then
+	echo 'All Tests OK'
+else
+	echo $ERRORS 'FAILED Tests'
+fi
+exit $ERRORS
diff --git a/tests/test_sample_error.sh b/tests/test_sample_error.sh
new file mode 100644
--- /dev/null
+++ b/tests/test_sample_error.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+SOCK=`mktemp -u`
+
+EXPECTED_ERRORS='SampleError.hs:9:5: Not in scope: `foo'\'''
+
+if ERRORS=`$HDEVTOOLS check --socket=$SOCK SampleError.hs`
+then
+	false
+elsh
+	[ "$ERRORS" = "$EXPECTED_ERRORS" ]
+fi
+
+$HDEVTOOLS --socket=$SOCK --stop-server
diff --git a/tests/test_simple_check.sh b/tests/test_simple_check.sh
new file mode 100644
--- /dev/null
+++ b/tests/test_simple_check.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+set -e
+
+SOCK=`mktemp -u`
+
+ERRORS=`$HDEVTOOLS check --socket=$SOCK Simple.hs`
+
+[ -z "$ERRORS" ]
+
+$HDEVTOOLS --socket=$SOCK --stop-server
diff --git a/tests/test_start_stop.sh b/tests/test_start_stop.sh
new file mode 100644
--- /dev/null
+++ b/tests/test_start_stop.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+set -e
+
+SOCK=`mktemp -u`
+
+echo '> Starting the server'
+$HDEVTOOLS --socket=$SOCK --start-server
+
+echo '> Checking status'
+$HDEVTOOLS --socket=$SOCK --status
+
+echo '> Checking that the socket file exists'
+if [ ! -S $SOCK ]; then false; fi
+
+echo '> Stopping the server'
+$HDEVTOOLS --socket=$SOCK --stop-server
+
+echo '> Checking that the socket file no longer exists'
+if [ -e $SOCK ]; then false; fi
