diff --git a/Analyse/Everything.hs b/Analyse/Everything.hs
--- a/Analyse/Everything.hs
+++ b/Analyse/Everything.hs
@@ -43,8 +43,8 @@
 import System.Random(RandomGen)
 
 -- | Performs analysis of the entire codebase.
-analyseEverything :: (RandomGen g) => g -> [ModName] -> ParsedModules
-                  -> DocElement
+analyseEverything           :: (RandomGen g) => g -> [ModName] -> ParsedModules
+                            -> DocElement
 analyseEverything g exps hm = Section sec elems
     where
       cd = codeToGraph exps hm
@@ -87,7 +87,7 @@
 
 clustersOf      :: (RandomGen g) => g -> HSData -> Maybe DocElement
 clustersOf g cd = Just $ Section sec [ text, gc, textAfter
-                                     , blank, cwMsg, cw, blank, rngMsg, rng]
+                                     , blank, cwMsg, cw] -- , blank, rngMsg, rng]
     where
       blank = Paragraph [BlankSpace]
       sec = Text "Visualisation of overall function calls"
@@ -95,15 +95,18 @@
       text = Paragraph
              [Text "Here is the current module grouping of functions:"]
       lbl = "Current module groupings"
-      textAfter = Paragraph [Text "Here are two proposed module groupings:"]
+      textAfter = Paragraph [Text "Here is a proposed alternate module grouping:"]
+                  -- [Text "Here are two proposed module groupings:"]
       cwMsg = Paragraph [Emphasis $ Text "Using the Chinese Whispers algorithm:"]
       cw = GraphImage ("codeCW", Text cwLbl, drawClusters cwLbl (chineseWhispers g) cd)
       cwLbl = "Chinese Whispers module suggestions"
+{-
       rngMsg = Paragraph [Emphasis $ Text "Using the Relative Neighbourhood algorithm:"]
       rng = GraphImage ("codeRNG", Text rngLbl, drawClusters lbl relNbrhd cd)
       -- Being naughty to avoid having to define drawClusters'
       relNbrhd = relativeNeighbourhood $ directedData cd
       rngLbl = "Relative Neighbourhood module suggestions"
+-}
 
 componentAnal :: HSData -> Maybe DocElement
 componentAnal cd
diff --git a/Analyse/Utils.hs b/Analyse/Utils.hs
--- a/Analyse/Utils.hs
+++ b/Analyse/Utils.hs
@@ -37,7 +37,7 @@
 import Data.GraphViz
 
 import Data.List(groupBy, sortBy)
-import Data.Maybe(isJust)
+-- import Data.Maybe(isJust)
 import Data.Function(on)
 import qualified Data.Set as S
 import Data.Set(Set)
@@ -240,7 +240,11 @@
 clustAttributes' = return . GraphAttrs . clustAttributes
 
 modClustAttrs   :: ModName -> [GlobalAttributes]
-modClustAttrs m = [GraphAttrs [Label . StrLabel $ nameOfModule m]]
+modClustAttrs m = [GraphAttrs [ Label . StrLabel $ nameOfModule m
+                              , Style [SItem Filled []]
+                              , FillColor $ ColorName "wheat1"
+                              ]
+                  ]
 
 -- -----------------------------------------------------------------------------
 
@@ -249,11 +253,15 @@
 drawClusters gid cf dg = setID (Str gid)
                          $ graphvizClusters dg'
                                             gAttrs
-                                            (const [])
+                                            (const cAttr)
                                             nAttr
                                             callAttributes'
     where
       gAttrs = [] -- [GraphAttrs [Label $ StrLabel t]]
+      cAttr = [GraphAttrs [ Style [SItem Filled []]
+                          , FillColor $ ColorName "wheat1"
+                          ]
+              ]
       dg' = updateGraph (compactSame . cf . collapseStructures') dg
       rs = getRoots dg
       ls = getLeaves dg
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,19 @@
+Changes since 0.5.1.0
+=====================
+
+* Add support for passing a single Haskell source file rather than a
+  Cabal file as the argument, as requested by Curt Sampson.
+
+* Shade backgrounds of modules when clustering Entities.
+
+* RelativeNeighbourhood doesn't provide good alternate modules and
+  takes up too much runtime, and so has been removed.
+
+Changes since 0.5.0.0
+=====================
+
+* Re-write of parsing.
+
+* Usage of new graphviz and Graphalyze features.
+
+* More abstraction into common routines into Analyse.Utils
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -31,6 +31,7 @@
 module Main where
 
 import Parsing
+import Parsing.Types(nameOfModule)
 import Analyse
 
 import Data.Graph.Analysis
@@ -44,15 +45,16 @@
 
 import Data.Char(toLower)
 import Data.List(nub)
-import Data.Maybe(isJust, fromJust, listToMaybe, catMaybes)
+import Data.Maybe(isJust, fromJust, catMaybes)
+import qualified Data.Map as M
 import System.IO(hPutStrLn, stderr)
 import System.Directory( getCurrentDirectory
                        , doesDirectoryExist
+                       , doesFileExist
                        , getDirectoryContents)
 import System.FilePath( dropFileName
                       , dropExtension
                       , takeExtension
-                      , extSeparator
                       , isPathSeparator
                       , (</>)
                       , (<.>))
@@ -68,22 +70,16 @@
 
 main :: IO ()
 main = do input <- getArgs
-          let mcbl = getCabalFile input
-          case mcbl of
-            Nothing
-                -> putErrLn "Please pass in a .cabal file"
-            Just cbl
-                -> do pcbl <- parseCabal cbl
-                      case pcbl of
-                        Nothing
-                            -> putErrLn $ unwords [cbl,"is unparseable"]
-                        Just (nm,exps)
-                            -> do let dir = dropFileName cbl
-                                  dir' <- if null dir
-                                            then getCurrentDirectory
-                                            else return dir
-                                  hms <- parseFilesFrom dir'
-                                  analyseCode dir nm exps hms
+          mInfo <- getPkgInfo input
+          case mInfo of
+            Nothing -> putErrLn "No parseable package information found."
+            Just (f,(nm,exps))
+                -> do let dir = dropFileName f
+                      dir' <- if null dir
+                                then getCurrentDirectory
+                                else return dir
+                      hms <- parseFilesFrom dir'
+                      analyseCode dir nm exps hms
 
 programmeName :: String
 programmeName = "SourceGraph"
@@ -96,6 +92,24 @@
 
 -- -----------------------------------------------------------------------------
 
+getPkgInfo :: [String] -> IO (Maybe (FilePath, (String, [ModName])))
+getPkgInfo [] = do putErrLn "Please provide either a Cabal file \
+                            \or a Haskell source file as an argument."
+                   return Nothing
+getPkgInfo [f]
+    | isCabalFile f   = withF parseCabal
+    | isHaskellFile f = withF parseMain
+    where
+      withF func = do ex <- doesFileExist f
+                      if ex
+                         then addF $ func f
+                         else do putErrLn "The provided file does not exist."
+                                 return Nothing
+      addF = fmap (fmap ((,) f))
+getPkgInfo _        = do putErrLn "Please provide a single Cabal \
+                                  \or Haskell source file as an argument."
+                         return Nothing
+
 parseCabal    :: FilePath -> IO (Maybe (String, [ModName]))
 parseCabal fp = do gpd <- try $ readPackageDescription silent fp
                    case gpd of
@@ -121,11 +135,21 @@
                  | otherwise        = error "No exposed modules"
             exps' = map fpToModule exps
 
-getCabalFile :: [FilePath] -> Maybe FilePath
-getCabalFile = listToMaybe . filter isCabalFile
-    where
-      isCabalFile f  = takeExtension f == extSeparator : "cabal"
+isCabalFile :: FilePath -> Bool
+isCabalFile = hasExt "cabal"
 
+parseMain    :: FilePath -> IO (Maybe (String, [ModName]))
+parseMain fp = do pms <- parseHaskellFiles [fp]
+                  let mn = fst $ M.findMin pms
+                  return $ Just (nameOfModule mn, [mn])
+
+-- | Determine if this is the path of a Haskell file.
+isHaskellFile    :: FilePath -> Bool
+isHaskellFile fp = any (flip hasExt fp) haskellExtensions
+
+hasExt     :: String -> FilePath -> Bool
+hasExt ext = (==) ext . drop 1 . takeExtension
+
 fpToModule :: FilePath -> ModName
 fpToModule = createModule . map pSep
     where
@@ -137,10 +161,11 @@
 
 -- | Recursively parse all files from this directory
 parseFilesFrom    :: FilePath -> IO ParsedModules
-parseFilesFrom fp = do files <- getHaskellFilesFrom fp
-                       cnts <- readFiles files
-                       return $ parseHaskell cnts
+parseFilesFrom fp = parseHaskellFiles =<< getHaskellFilesFrom fp
 
+parseHaskellFiles :: [FilePath] -> IO ParsedModules
+parseHaskellFiles = liftM parseHaskell . readFiles
+
 -- -----------------------------------------------------------------------------
 
 -- Reading in the files.
@@ -168,12 +193,8 @@
                       recursiveFiles <- concatMapM getHaskellFilesFrom dirs
                       return (hFiles ++ recursiveFiles)
 
--- | Determine if this is the path of a Haskell file.
-isHaskellFile   :: FilePath -> Bool
-isHaskellFile f = takeExtension f `elem` haskellExtensions
-
 haskellExtensions :: [FilePath]
-haskellExtensions = map (extSeparator :) ["hs","lhs"]
+haskellExtensions = ["hs","lhs"]
 
 -- | Read in all the files that it can.
 readFiles :: [FilePath] -> IO [FileContents]
diff --git a/SourceGraph.cabal b/SourceGraph.cabal
--- a/SourceGraph.cabal
+++ b/SourceGraph.cabal
@@ -1,8 +1,35 @@
 Name:                SourceGraph
-Version:             0.5.0.0
+Version:             0.5.1.0
 Synopsis:            Use graph-theory to analyse your code
-Description:         SourceGraph uses the Graphalyze library to analyse
-                     Cabalized Haskell code.
+Description: {
+Statically analyse Haskell source code using graph-theoretic
+techniques.
+.
+To use SourceGraph, call it as either:
+.
+> SourceGraph path/to/Foo.cabal
+.
+Or, if your project doesn't use Cabal, then there is limited support
+for using an overall module from your program\/library:
+.
+> SourceGraph path/to/Foo.hs
+.
+Note that the Cabal method is preferred, as it is better able to
+determine the project name and exported modules (when passing a
+Haskell file to SourceGraph, it uses that module's name as the overall
+name of project and assumes that it is the only exported module; as
+such, it works better for programs than libraries).
+.
+Whichever way your run SourceGraph, it then creates a @SourceGraph@
+subdirectory in the same directory as the file that was passed to it,
+and within that subdirectory creates the analysis report in
+@Foo.html@.
+.
+SourceGraph is still experimental in terms of its ability to parse and
+properly understand Haskell source code and in the types of analyses
+it performs.
+}
+
 Category:            Development
 License:             GPL
 License-file:        COPYRIGHT
@@ -12,6 +39,7 @@
 Cabal-Version:       >= 1.6
 Build-Type:          Simple
 Extra-Source-Files: TODO
+                    ChangeLog
                     KnownProblems.txt
                     ParsingProblems.txt
 
