diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,36 @@
+Version 0.6.6 released 06 Nov 2009
+
+* Require filestore >= 0.3.3, which closes a security
+  vulnerability.
+
+* Don't allow web file uploads to the static or templates directory,
+  even if these are subdirectories of the repository directory.
+  We don't want users uploading new CSS, javascript, or templates
+  that might break the site.
+
+* Renamed gitit-dog.png -> logo.png in data/static/img.
+  This way the logo will show up even without a local img directory.
+  Thanks to Thomas Hartmann for the patch.
+
+* Return 404 when page not found.  Thanks to Richard Fergie.
+
+* Improved layout of Export button.
+
+* Added links for atom feeds to sitenav.st and pagetools.st, to
+  make the feeds more discoverable.
+
+* Minor code safety improvements.
+
+* Check for commit messages consisting of whitespace.
+  Commit messages consisting only of whitespace characters are
+  rejected by Git as empty. Gitit should behave similarly.
+
+* Allow gitit to start up if custom template directory not found.
+  Thanks to Thomas Hartmann.
+
+* Fixed incorrect usage of nullGroup (a debugging function).  Thanks
+  to Thomas Hartmann.
+
 Version 0.6.5 released 06 Oct 2009
 
 * Added metadata to Page and Context, provided askMeta for plugins.
@@ -7,6 +40,8 @@
 * Added PigLatin plugin to demonstrate use of askMeta.
 
 * Display informative message on authentication failure.
+
+* Fixed library stanza in cabal file so plugins are properly enabled.
 
 Version 0.6.4 released 28 Sep 2009
 
diff --git a/Network/Gitit.hs b/Network/Gitit.hs
--- a/Network/Gitit.hs
+++ b/Network/Gitit.hs
@@ -118,6 +118,7 @@
 import Prelude hiding (readFile)
 import qualified Data.ByteString.Char8 as B
 import System.FilePath ((</>))
+import Safe
 
 -- | Happstack handler for a gitit wiki.
 wiki :: Config -> ServerPart Response
@@ -142,7 +143,7 @@
 fileServeStrict' ps p = do
   rq <- askRq
   resp <- fileServeStrict ps p
-  if rsCode resp == 404 || last (rqUri rq) == '/'
+  if rsCode resp == 404 || lastNote "fileServeStrict'" (rqUri rq) == '/'
      then mzero  -- pass through if not found or directory index
      else do
        -- turn off compresion filter unless it's text
@@ -192,7 +193,7 @@
   , showPage
   , guardPath isSourceCode >> methodOnly GET >> showHighlightedSource
   , handleAny
-  , guardPath isPage >> createPage
+  , notFound =<< (guardPath isPage >> createPage)
   ]
 
 -- | Recompiles the gitit templates.
diff --git a/Network/Gitit/Config.hs b/Network/Gitit/Config.hs
--- a/Network/Gitit/Config.hs
+++ b/Network/Gitit/Config.hs
@@ -24,6 +24,7 @@
                             , readMimeTypesFile
                             , getDefaultConfig )
 where
+import Safe
 import Network.Gitit.Types
 import Network.Gitit.Server (mimeTypes)
 import Network.Gitit.Framework
@@ -235,7 +236,7 @@
 readNumber :: (Read a) => String -> String -> a
 readNumber opt "" = error $ opt ++ " must be a number."
 readNumber opt x  =
-  let x' = case last x of
+  let x' = case lastNote "readNumber" x of
                 'K'  -> init x ++ "000"
                 'M'  -> init x ++ "000000"
                 'G'  -> init x ++ "000000000"
@@ -248,9 +249,9 @@
 splitCommaList l =
   let (first,rest) = break (== ',') l
       first' = lrStrip first
-  in  if null rest
-         then if null first' then [] else [first']
-         else first' : splitCommaList (tail rest)
+  in case rest of
+         []     -> if null first' then [] else [first']
+         (_:rs) -> first' : splitCommaList rs
 
 lrStrip :: String -> String
 lrStrip = reverse . dropWhile isWhitespace . reverse . dropWhile isWhitespace
diff --git a/Network/Gitit/ContentTransformer.hs b/Network/Gitit/ContentTransformer.hs
--- a/Network/Gitit/ContentTransformer.hs
+++ b/Network/Gitit/ContentTransformer.hs
@@ -351,7 +351,10 @@
 highlightSource Nothing = mzero
 highlightSource (Just source) = do
   file <- getFileName
-  let lang' = head $ languagesByExtension $ takeExtension file
+  -- let lang' = head $ languagesByExtension $ takeExtension file
+  let lang' = case languagesByExtension $ takeExtension file of
+               []    -> error "highlightSource, no lang'"
+               (l:_) -> l
   case highlightAs lang' (filter (/='\r') source) of
        Left _       -> mzero
        Right res    -> return $ formatAsXHtml [OptNumberLines] lang' $! res
diff --git a/Network/Gitit/Feed.hs b/Network/Gitit/Feed.hs
--- a/Network/Gitit/Feed.hs
+++ b/Network/Gitit/Feed.hs
@@ -47,9 +47,13 @@
   let path' = maybe "" id mbPath
   when (null $ fcBaseUrl cfg) $ error "base-url in the config file is null."
   rs <- changeLog cfg a mbPath
-  let rsShifted = if null rs
+{-  let rsShifted = if null rs
                      then []
                      else head rs : init rs   -- so we can get revids for diffs
+-}
+  let rsShifted = case rs of
+                     [] -> []
+                     (x:_) -> x : init rs   -- so we can get revids for diffs
   now <- liftM formatFeedTime getCurrentTime
   return $ Feed { feedId = fcBaseUrl cfg ++ "/" ++ path'
                 , feedTitle = TextString $ fcTitle cfg
@@ -121,8 +125,15 @@
                          , linkOther = [] } 
           (firstpath, fromrev) =
                       if null path'
-                         then case head rv of
+                         {- then case head rv of
                                    Modified f -> (dePage f, "&from=" ++ revId prevRevision)
+                                   Added f    -> (dePage f, "")
+                                   Deleted f  -> (dePage f, "&from=" ++ revId prevRevision)
+                         else (path',"") -}
+                         then case rv of
+                                [] -> error "revToEntry, null rv"
+                                (rev:_) -> case rev of 
+                                   Modified f -> (dePage f, "&from=" ++ revId prevRevision)                                
                                    Added f    -> (dePage f, "")
                                    Deleted f  -> (dePage f, "&from=" ++ revId prevRevision)
                          else (path',"")
diff --git a/Network/Gitit/Framework.hs b/Network/Gitit/Framework.hs
--- a/Network/Gitit/Framework.hs
+++ b/Network/Gitit/Framework.hs
@@ -56,6 +56,7 @@
                                , filestoreFromConfig
                                )
 where
+import Safe
 import Network.Gitit.Server
 import Network.Gitit.State
 import Network.Gitit.Types
@@ -236,9 +237,9 @@
 splitOn :: Eq a => a -> [a] -> [[a]]
 splitOn c cs =
   let (next, rest) = break (==c) cs
-  in  if null rest
-         then [next]
-         else next : splitOn c (tail rest)
+  in case rest of
+         []     -> [next]
+         (_:rs) -> next : splitOn c rs 
 
 -- | Returns path portion of URI, without initial @\/@.
 -- Consecutive spaces are collapsed.  We don't want to distinguish
@@ -310,7 +311,7 @@
   base <- getWikiBase
   uri' <- liftM rqUri askRq
   let localpath = drop (length base) uri'
-  if length localpath > 1 && last uri' == '/'
+  if length localpath > 1 && lastNote "guardIndex" uri' == '/'
      then return ()
      else mzero
 
diff --git a/Network/Gitit/Handlers.hs b/Network/Gitit/Handlers.hs
--- a/Network/Gitit/Handlers.hs
+++ b/Network/Gitit/Handlers.hs
@@ -53,7 +53,9 @@
                       , feedHandler
                       )
 where
+import Safe
 import Data.FileStore
+import Data.FileStore.Utils (isInsideDir)
 import Network.Gitit.Server
 import Network.Gitit.Framework
 import Network.Gitit.Layout
@@ -77,7 +79,7 @@
 import Data.List (intersperse, nub, sortBy, find, isPrefixOf, inits, sort)
 import Data.Maybe (fromMaybe, mapMaybe, isJust, catMaybes)
 import Data.Ord (comparing)
-import Data.Char (toLower)
+import Data.Char (toLower, isSpace)
 import Control.Monad.Reader
 import qualified Data.ByteString.Lazy as B
 import qualified Data.ByteString as S
@@ -197,10 +199,17 @@
                       if e == NotFound
                          then return False
                          else throwIO e >> return True
+  inStaticDir <- liftIO $
+                  (repositoryPath cfg </> wikiname) `isInsideDir` staticDir cfg
+  inTemplatesDir <- liftIO $
+                  (repositoryPath cfg </> wikiname) `isInsideDir` templatesDir cfg
   let imageExtensions = [".png", ".jpg", ".gif"]
   let errors = validate
-                 [ (null logMsg, "Description cannot be empty.")
+                 [ (null . filter (not . isSpace) $ logMsg,
+                    "Description cannot be empty.")
                  , (null origPath, "File not found.")
+                 , (inStaticDir,  "Destination is inside static directory.")
+                 , (inTemplatesDir,  "Destination is inside templates directory.")
                  , (not overwrite && exists, "A file named '" ++ wikiname ++
                     "' already exists in the repository: choose a new name " ++
                     "or check the box to overwrite the existing file.")
@@ -601,7 +610,7 @@
   let oldSHA1 = pSHA1 params
   fs <- getFileStore
   base' <- getWikiBase
-  if null logMsg
+  if null . filter (not . isSpace) $ logMsg
      then withMessages ["Description cannot be empty."] editPage
      else do
        when (length editedText > fromIntegral (maxUploadSize cfg)) $
@@ -663,10 +672,10 @@
       updirs = drop 1 $ inits $ splitPath $ '/' : prefix
       uplink = foldr (\d accum ->
                   concatHtml [ anchor ! [theclass "updir",
-                                         href $ if length d == 1
+                                         href $ if length d <= 1
                                                    then base' ++ "/_index"
                                                    else base' ++ joinPath d] <<
-                  last d, accum]) noHtml updirs
+                  lastNote "fileListToHtml" d, accum]) noHtml updirs
   in uplink +++ ulist ! [theclass "index"] << map fileLink files
 
 -- NOTE:  The current implementation of categoryPage does not go via the
diff --git a/Network/Gitit/Initialize.hs b/Network/Gitit/Initialize.hs
--- a/Network/Gitit/Initialize.hs
+++ b/Network/Gitit/Initialize.hs
@@ -68,21 +68,23 @@
   ct <- compilePageTemplate tempsDir
   updateGititState $ \st -> st{renderPage = defaultRenderPage ct}
 
--- | Compile a master page template named @page.st@ in the directory specified.
+--- | Compile a master page template named @page.st@ in the directory specified.
 compilePageTemplate :: FilePath -> IO (T.StringTemplate String)
 compilePageTemplate tempsDir = do
   defaultGroup <- getDataFileName ("data" </> "templates") >>= T.directoryGroup
-  templateExists <- doesDirectoryExist tempsDir
-  customGroup <- if templateExists
-                    then T.directoryGroup tempsDir
-                    else return T.nullGroup
-  -- default templates from data directory will be "shadowed"
-  -- by templates from the user's template dir
-  let combinedGroup = T.mergeSTGroups customGroup defaultGroup
+  customExists <- doesDirectoryExist tempsDir
+  combinedGroup <-
+    if customExists
+       -- default templates from data directory will be "shadowed"
+       -- by templates from the user's template dir
+       then do customGroup <- T.directoryGroup tempsDir
+               return $ T.mergeSTGroups customGroup defaultGroup
+       else do logM "gitit" WARNING $ "Custom template directory not found"
+               return defaultGroup
   case T.getStringTemplate "page" combinedGroup of
         Just t    -> return t
         Nothing   -> error "Could not get string template"
- 
+
 -- | Create templates dir if it doesn't exist.
 createTemplateIfMissing :: Config -> IO ()
 createTemplateIfMissing conf' = do
@@ -168,7 +170,7 @@
       logM "gitit" WARNING $ "Created " ++ (icondir </> f)
     -}
 
-    logopath <- getDataFileName $ "data" </> "static" </> "img" </> "gitit-dog.png"
+    logopath <- getDataFileName $ "data" </> "static" </> "img" </> "logo.png"
     createDirectoryIfMissing True $ staticdir </> "img"
     copyFile logopath $ staticdir </> "img" </> "logo.png"
     logM "gitit" WARNING $ "Created " ++ (staticdir </> "img" </> "logo.png")
diff --git a/Network/Gitit/Layout.hs b/Network/Gitit/Layout.hs
--- a/Network/Gitit/Layout.hs
+++ b/Network/Gitit/Layout.hs
@@ -107,6 +107,7 @@
          value (fromJust rev)] | isJust rev ] ++
      [ select ! [name "format"] <<
          map ((\f -> option ! [value f] << f) . fst) exportFormats
+     , primHtmlChar "nbsp" 
      , submit "export" "Export" ])
 exportBox _ _ _ = noHtml
 
diff --git a/Network/Gitit/Server.hs b/Network/Gitit/Server.hs
--- a/Network/Gitit/Server.hs
+++ b/Network/Gitit/Server.hs
@@ -57,7 +57,8 @@
   addrs <- getAddrInfo (Just defaultHints) (Just hostname) Nothing
   if null addrs
      then return Nothing
-     else return $ Just $ takeWhile (/=':') $ show $ addrAddress $ head addrs
-
+     else return $ Just $ takeWhile (/=':') $ show $ addrAddress $ case addrs of -- head addrs
+                                                                     [] -> error $ "lookupIPAddr, no addrs"
+                                                                     (x:_) -> x
 getHost :: ServerMonad m => m (Maybe String)
 getHost = liftM (maybe Nothing (Just . U.toString)) $ getHeaderM "Host"
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -520,9 +520,10 @@
 - Robin Green helped improve the plugin API and interface, and
   fixed a security problem with the reset password code.
 - Thomas Hartman helped improve the index page, making directory
-  browsing persistent.
+  browsing persistent, and fixed a bug in template recompilation.
 - Justin Bogner improved the appearance of the preview button.
 - Kohei Ozaki contributed the ImgTexPlugin.
+- Michael Terepeta improved validation of change descriptions.
 - mightybyte suggested making gitit available as a library,
   and contributed a patch to ifLoggedIn that was needed to
   make gitit usable with a custom authentication scheme.
diff --git a/data/static/img/gitit-dog.png b/data/static/img/gitit-dog.png
deleted file mode 100644
Binary files a/data/static/img/gitit-dog.png and /dev/null differ
diff --git a/data/static/img/icons/feed.png b/data/static/img/icons/feed.png
new file mode 100644
Binary files /dev/null and b/data/static/img/icons/feed.png differ
diff --git a/data/static/img/logo.png b/data/static/img/logo.png
new file mode 100644
Binary files /dev/null and b/data/static/img/logo.png differ
diff --git a/data/templates/pagetools.st b/data/templates/pagetools.st
--- a/data/templates/pagetools.st
+++ b/data/templates/pagetools.st
@@ -5,6 +5,9 @@
       <li><a href="$base$/_showraw$pageUrl$$if(revision)$?revision=$revision$$endif$">Raw page source</a></li>
       <li><a href="$base$$pageUrl$?printable$if(revision)$&amp;revision=$revision$$endif$">Printable version</a></li>
       <li><a href="$base$/_delete$pageUrl$">Delete this page</a></li>
+      $if(feed)$
+      <li><a href="$base$/_feed$pageUrl$" type="application/atom+xml" rel="alternate" title="This page's ATOM Feed">Atom feed</a> <img alt="feed icon" src="$base$/img/icons/feed.png"/></li>
+      $endif$
     </ul>
     $exportbox$
   </fieldset>
diff --git a/data/templates/sitenav.st b/data/templates/sitenav.st
--- a/data/templates/sitenav.st
+++ b/data/templates/sitenav.st
@@ -8,6 +8,9 @@
       <li><a href="$base$/_random">Random page</a></li>
       <li><a href="$base$/_activity">Recent activity</a></li>
       <li><a href="$base$/_upload">Upload a file</a></li>
+      $if(feed)$
+      <li><a href="$base$/_feed" type="application/atom+xml" rel="alternate" title="ATOM Feed">Atom feed</a> <img alt="feed icon" src="$base$/img/icons/feed.png"/></li>
+      $endif$
       <li><a href="$base$/Help">Help</a></li>
     </ul>
     <form action="$base$/_search" method="post" id="searchform">
diff --git a/gitit.cabal b/gitit.cabal
--- a/gitit.cabal
+++ b/gitit.cabal
@@ -1,5 +1,5 @@
 name:                gitit
-version:             0.6.5
+version:             0.6.6
 Cabal-version:       >= 1.2
 build-type:          Simple
 synopsis:            Wiki using happstack, git or darcs, and pandoc.
@@ -46,7 +46,7 @@
                      data/static/css/ie.css, data/static/css/hk-pyg.css,
                      data/static/css/reset-fonts-grids.css, data/static/css/base-min.css,
                      data/static/css/custom.css,
-                     data/static/img/gitit-dog.png,
+                     data/static/img/logo.png, data/static/img/icons/feed.png,
                      data/static/img/icons/folder.png, data/static/img/icons/page.png,
                      data/static/js/dragdiff.js, data/static/js/jquery.min.js,
                      data/static/js/uploadForm.js, data/static/js/jquery-ui.packed.js,
@@ -98,7 +98,7 @@
     exposed-modules: Network.Gitit.Interface
     build-depends:   ghc, ghc-paths
     cpp-options:     -D_PLUGINS
-  build-depends:     base >= 3, pandoc >= 1.1, filepath
+  build-depends:     base >= 3, pandoc >= 1.1, filepath, safe
   ghc-options:       -Wall
   ghc-prof-options:  -auto-all -caf-all
 
@@ -109,7 +109,7 @@
                      pandoc >= 1.2, process, filepath, directory, mtl, cgi,
                      network, old-time, highlighting-kate, bytestring,
                      utf8-string, SHA > 1, HTTP, HStringTemplate, random,
-                     network >= 2.1.0.0, recaptcha >= 0.1, filestore >= 0.3.2,
+                     network >= 2.1.0.0, recaptcha >= 0.1, filestore >= 0.3.3,
                      datetime, zlib, url, happstack-server >= 0.3.3 && < 0.4,
                      happstack-util >= 0.3.2 && < 0.4, xml >= 1.3.4,
                      hslogger >= 1 && < 1.1, ConfigFile >= 1, feed >= 0.3.6,
