diff --git a/Javav.cabal b/Javav.cabal
new file mode 100644
--- /dev/null
+++ b/Javav.cabal
@@ -0,0 +1,26 @@
+Name:               Javav
+Version:            0.0.1
+Author:             Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>
+Maintainer:         Tony Morris
+Copyright:          Tony Morris
+License:            BSD3
+License-File:       LICENSE
+Synopsis:           A utility to print the target version of Java class files.
+Category:           Language
+Description:        A utility to print the target version of Java class files.
+Cabal-version:      >= 1.2
+Build-Type:         Simple
+
+Flag small_base
+  Description:      Choose the new, split-up base package.
+
+Executable javav
+  Main-Is:          Main.hs
+  Build-Depends:
+                    base < 5 && >= 3
+
+  GHC-Options:
+                    -Wall
+
+  Other-Modules:
+                    Language.Java.Javav
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/Language/Java/Javav.hs b/Language/Java/Javav.hs
new file mode 100644
--- /dev/null
+++ b/Language/Java/Javav.hs
@@ -0,0 +1,87 @@
+module Language.Java.Javav where
+
+
+import System.IO
+import System.IO.Error
+import Data.Maybe
+import Control.Arrow
+
+type Version =
+  String
+
+versions ::
+  [((Char, Char), Version)]
+versions =
+  [ (('\NUL', '2'), "1.6 (50.0 0x32)")
+  , (('\NUL', '1'), "1.5 (49.0 0x31)")
+  , (('\NUL', '0'), "1.4 (48.0 0x30)")
+  , (('\NUL', '/'), "1.3 (47.0 0x29)")
+  , (('\NUL', '.'), "1.2 (46.0 0x28)")
+  , (('\NUL', '-'), "1.1 (45.0 0x28)")
+  ]
+
+type Error =
+  String
+
+alreadyInUseError ::
+  Error
+alreadyInUseError =
+  "-u-"
+
+doesNotExistError ::
+  Error
+doesNotExistError =
+  "-e-"
+
+permissionError ::
+  Error
+permissionError =
+  "-p-"
+
+unknownError ::
+  Error
+unknownError =
+  "-?-"
+
+handleError ::
+  IOError
+  -> Error
+handleError e =
+  let err = first ($e) `fmap`
+              [ (isAlreadyInUseError, alreadyInUseError)
+              , (isDoesNotExistError, doesNotExistError)
+              , (isPermissionError  , permissionError)
+              ]
+  in unknownError `fromMaybe` lookup True err
+
+versionOutput ::
+  Char
+  -> Char
+  -> Version
+versionOutput c1 c2 =
+  "-?-" `fromMaybe` lookup (c1, c2) versions
+
+version ::
+  FilePath
+  -> IO Version
+version n =
+  (withBinaryFile n ReadMode (\h ->
+    do hSeek h AbsoluteSeek 6
+       c1 <- hGetChar h
+       hSeek h AbsoluteSeek 7
+       c2 <- hGetChar h
+       return (versionOutput c1 c2))) `catch`
+  (return . handleError)
+
+version' ::
+  [FilePath]
+  -> IO [Version]
+version' =
+  mapM version
+
+printv ::
+  [FilePath]
+  -> IO ()
+printv n =
+  do s <- version' n
+     mapM_ (\(t, o) -> putStrLn (t ++ ' ' : o)) (zip s n)
diff --git a/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,23 @@
+module Main where
+
+import Language.Java.Javav
+import System.Environment
+
+main ::
+  IO ()
+main =
+  do a <- getArgs
+     if null a
+        then mapM_ putStrLn $
+                     [ "Prints the Java version of one or more class files"
+                     , "Usage: javav <filename(s)>"
+                     ] ++
+                     ("  " ++) `fmap`
+                       [ "Error conditions"
+                       , alreadyInUseError ++ " File is in use"
+                       , doesNotExistError ++ " File does not exist"
+                       , permissionError ++ " File does not have read permission"
+                       , unknownError ++ " An unknown error occurred"
+                       ]
+        else printv a
+
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
+
