diff --git a/Config/Default.hs b/Config/Default.hs
--- a/Config/Default.hs
+++ b/Config/Default.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Config/Reader.hs b/Config/Reader.hs
--- a/Config/Reader.hs
+++ b/Config/Reader.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Manatee/Extension/Reader.hs b/Manatee/Extension/Reader.hs
--- a/Manatee/Extension/Reader.hs
+++ b/Manatee/Extension/Reader.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Manatee/Extension/Reader/PageMode.hs b/Manatee/Extension/Reader/PageMode.hs
--- a/Manatee/Extension/Reader/PageMode.hs
+++ b/Manatee/Extension/Reader/PageMode.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Manatee/Extension/Reader/ReaderBuffer.hs b/Manatee/Extension/Reader/ReaderBuffer.hs
--- a/Manatee/Extension/Reader/ReaderBuffer.hs
+++ b/Manatee/Extension/Reader/ReaderBuffer.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -18,21 +18,24 @@
 
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE TemplateHaskell #-}
 module Manatee.Extension.Reader.ReaderBuffer where
 
-import Config.Import
 import Codec.Binary.UTF8.String
+import Config.Import
 import Control.Applicative
 import Control.Concurrent
 import Control.Concurrent.STM 
 import Control.Monad
 import DBus.Client hiding (Signal)
+import Data.Binary
+import Data.DeriveTH
 import Data.Map (Map)
 import Data.Maybe (fromMaybe)
 import Data.Ord (comparing)
 import Data.Typeable
-import Graphics.UI.Gtk.General.General
-import Graphics.UI.Gtk.ModelView.TreeSortable
+import Graphics.UI.Gtk hiding (get)
+import Manatee.Core.Config
 import Manatee.Core.Dynload
 import Manatee.Core.Types
 import Manatee.Extension.Reader.PageMode
@@ -59,9 +62,17 @@
                  ,readerBufferFeedNavOptions    :: [(NavItemOption, SortColumnId)]
                  ,readerBufferBroadcastChannel  :: TChan ReaderTChanSignal
                  ,readerBufferCustomize         :: ReaderCustomize
+                 ,readerBufferState             :: TVar ReaderState
                  }
     deriving Typeable
 
+data ReaderState =
+    ReaderState {readerStateFeedSelectedPath    :: (Maybe TreePath) 
+                ,readerStateItemSelectedPath    :: (Maybe TreePath)
+                ,readerStateItemScrolledPosition:: (Double, Double)
+                ,readerStateWebScrolledPosition :: (Double, Double)
+                }
+
 data ReaderTChanSignal = FeedUpdated FeedName
                          deriving (Show, Eq, Ord)
 
@@ -122,6 +133,11 @@
   niCompareRow NTitle   item1 item2 = return $ comparing fniTitle item1 item2
   niCompareRow NTime    item1 item2 = return $ comparing fniTime item1 item2 
 
+-- | Init state.
+readerInitState :: ReaderState      
+readerInitState = 
+  ReaderState Nothing Nothing (0, 0) (0, 0)
+
 -- | Create reader buffer.
 readerBufferNew :: String -> [String] -> Client -> PageId -> CustomizeWrap -> IO ReaderBuffer
 readerBufferNew path _ client pageId c = do
@@ -139,6 +155,7 @@
                          <*> pure (pairPred [NTitle, NTime])
                          <*> (newTChanIO :: IO (TChan ReaderTChanSignal))
                          <*> pure customize
+                         <*> newTVarIO readerInitState
 
   -- Fetch feed.
   readerBufferFetchFeed buffer
@@ -211,4 +228,18 @@
 readerCustomizeNew =
   fmap CustomizeWrap
        ReaderCustomize <$> newTVarIO feedInfos
+
+-- | Write state.
+readerBufferWriteState :: ReaderBuffer -> FilePath -> IO ()
+readerBufferWriteState buffer path = do
+  state <- readTVarIO $ readerBufferState buffer
+  writeConfigPath path state
+
+-- | Read state.
+readerBufferReadState :: ReaderBuffer -> FilePath -> IO ()  
+readerBufferReadState buffer path = do
+  state <- readConfigPath path readerInitState
+  writeTVarIO (readerBufferState buffer) state
+  
+$(derive makeBinary ''ReaderState)
 
diff --git a/Manatee/Extension/Reader/ReaderView.hs b/Manatee/Extension/Reader/ReaderView.hs
--- a/Manatee/Extension/Reader/ReaderView.hs
+++ b/Manatee/Extension/Reader/ReaderView.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -27,9 +27,9 @@
 import Data.Text.Lazy (Text)
 import Data.Typeable
 import Graphics.UI.Gtk hiding (Statusbar, statusbarNew, get)
-import Graphics.UI.Gtk.Gdk.SerializedEvent
 import Graphics.UI.Gtk.WebKit.WebFrame
 import Graphics.UI.Gtk.WebKit.WebView
+import Manatee.Core.Config
 import Manatee.Core.DBus
 import Manatee.Core.PageFrame
 import Manatee.Core.PageView
@@ -38,8 +38,8 @@
 import Manatee.Extension.Reader.Types
 import Manatee.Toolkit.General.Map
 import Manatee.Toolkit.General.Maybe
+import Manatee.Toolkit.General.STM
 import Manatee.Toolkit.Gtk.Concurrent
-import Manatee.Toolkit.Gtk.Gtk
 import Manatee.Toolkit.Gtk.ModelView
 import Manatee.Toolkit.Gtk.ScrolledWindow
 import Paths_manatee_reader
@@ -79,12 +79,17 @@
   pageBufferPackageName _       = fmap takeFileName getDataDir
 
 instance PageView ReaderView where
-    pageViewBuffer              = PageBufferWrap . readerViewBuffer
-    pageViewPlugId              = readerViewPlugId
-    pageViewBox                 = pageFrameBox . readerViewFrame
-    pageViewScrolledWindow      = readerViewScrolledWindow
-    pageViewFocus               = widgetGrabFocus . readerViewHPaned
-    pageViewHandleKeyAction     = readerViewHandleKeyAction
+    pageViewBuffer               = PageBufferWrap . readerViewBuffer
+    pageViewPlugId               = readerViewPlugId
+    pageViewFrame                = readerViewFrame
+    pageViewLocalKeymap _        = readerViewLocalKeymap
+    pageViewLocalCommandMap _    = readerViewLocalCommandMap
+    pageViewFocus                = widgetGrabFocus . readerViewHPaned
+    pageViewPropagateWidget      = castToWidget . readerViewHPaned
+    pageViewSaveState view       = readerViewSaveState view Nothing
+    pageViewRestoreState view    = readerViewRestoreState view Nothing
+    pageViewWriteState view path = readerViewSaveState view (Just path)
+    pageViewReadState view path  = readerViewRestoreState view (Just path)
 
 -- | Create reader view.
 readerViewNew :: ReaderBuffer -> PagePlugId -> IO ReaderView
@@ -389,13 +394,6 @@
       set cell [cellText   := niGetCellText info row
                ,cellXAlign := niGetCellXAlign info]
 
--- | Handle key action.
-readerViewHandleKeyAction :: ReaderView -> Text -> SerializedEvent -> IO ()  
-readerViewHandleKeyAction view keystoke sEvent = 
-  case M.lookup keystoke readerViewKeymap of
-    Just action -> action view
-    Nothing -> widgetPropagateEvent (readerViewHPaned view) sEvent
-
 -- | Select next feed.
 readerViewSelectNextFeed :: ReaderView -> IO ()
 readerViewSelectNextFeed view = do
@@ -501,28 +499,100 @@
       unless (null url) $   
              mkDaemonSignal (pageViewClient view) NewTab (NewTabArgs "PageBrowser" url [])
 
--- | Scrolled window.
-readerViewScrolledWindow :: ReaderView -> ScrolledWindow      
-readerViewScrolledWindow =
-    pageFrameScrolledWindow . readerViewFrame
+-- | Keymap.
+readerViewLocalKeymap :: Map Text Text
+readerViewLocalKeymap = 
+    M.fromList 
+         [("n",         "Next feed")
+         ,("p",         "Previous feed")
+         ,("N",         "Last feed")
+         ,("P",         "First feed")
+         ,("j",         "Next item")
+         ,("k",         "Previous item")
+         ,("Down",      "Next item")
+         ,("Up",        "Previous item")
+         ,("J",         "Last item")
+         ,("K",         "First item")
+         ,(",",         "Scroll step up")
+         ,(".",         "Scroll step down")
+         ,(" ",         "Scroll page up")
+         ,("b",         "Scroll page down")
+         ,("m",         "Read in browser")
+         ]
 
 -- | Keymap.
-readerViewKeymap :: Map Text (ReaderView -> IO ())
-readerViewKeymap = 
+readerViewLocalCommandMap :: Map Text (ReaderView -> IO ())
+readerViewLocalCommandMap = 
     M.fromList 
-         [("n",         readerViewSelectNextFeed)
-         ,("p",         readerViewSelectPrevFeed)
-         ,("N",         readerViewSelectLastFeed)
-         ,("P",         readerViewSelectFirstFeed)
-         ,("j",         readerViewSelectNextItem)
-         ,("k",         readerViewSelectPrevItem)
-         ,("Down",      readerViewSelectNextItem)
-         ,("Up",        readerViewSelectPrevItem)
-         ,("J",         readerViewSelectLastItem)
-         ,("K",         readerViewSelectFirstItem)
-         ,(",",         readerViewScrollWebViewStepUp)
-         ,(".",         readerViewScrollWebViewStepDown)
-         ,(" ",         readerViewScrollWebViewPageUp)
-         ,("b",         readerViewScrollWebViewPageDown)
-         ,("m",         readerViewBrowseInBrowser)
+         [("Next feed",         readerViewSelectNextFeed)
+         ,("Previous feed",     readerViewSelectPrevFeed)
+         ,("Last feed",         readerViewSelectLastFeed)
+         ,("First feed",        readerViewSelectFirstFeed)
+         ,("Next item",         readerViewSelectNextItem)
+         ,("Previous item",     readerViewSelectPrevItem)
+         ,("Last item",         readerViewSelectLastItem)
+         ,("First item",        readerViewSelectFirstItem)
+         ,("Scroll step up",    readerViewScrollWebViewStepUp)
+         ,("Scroll step down",  readerViewScrollWebViewStepDown)
+         ,("Scroll page up",    readerViewScrollWebViewPageUp)
+         ,("Scroll page down",  readerViewScrollWebViewPageDown)
+         ,("Read in browser",   readerViewBrowseInBrowser)
          ]
+
+-- | Save state.
+readerViewSaveState :: ReaderView -> Maybe FilePath -> IO ()
+readerViewSaveState (ReaderView {readerViewBuffer            = buffer
+                                ,readerViewTreeView          = feedView
+                                ,readerViewNavView           = itemView
+                                ,readerViewNavScrolledWindow = itemScrolledWindow
+                                ,readerViewWebScrolledWindow = webScrolledWindow}) 
+                    statePath = do
+  -- Get feed selected path.
+  feedSelectedPath <- treeViewGetSelectedPath feedView
+
+  -- Get item selected path.
+  itemSelectedPath <- treeViewGetSelectedPath itemView
+
+  -- Get item scroll position.
+  itemScrolledWindowPosition <- scrolledWindowGetValue itemScrolledWindow
+
+  -- Get web scroll position.
+  webScrolledWindowPosition <- scrolledWindowGetValue webScrolledWindow
+
+  -- Save state.
+  let state = ReaderState feedSelectedPath 
+                          itemSelectedPath 
+                          itemScrolledWindowPosition 
+                          webScrolledWindowPosition
+  case statePath of
+    Nothing   -> writeTVarIO (readerBufferState buffer) state
+    Just path -> writeConfigPath path state      
+
+-- | Restore state.
+readerViewRestoreState :: ReaderView -> Maybe FilePath -> IO ()
+readerViewRestoreState (ReaderView {readerViewBuffer            = buffer
+                                   ,readerViewTreeView          = feedView
+                                   ,readerViewNavView           = itemView
+                                   ,readerViewNavScrolledWindow = itemScrolledWindow
+                                   ,readerViewWebScrolledWindow = webScrolledWindow})
+                       statePath = do
+  bufferState <- readTVarIO (readerBufferState buffer)
+  (ReaderState feedSelectedPath 
+               itemSelectedPath 
+               itemScrolledWindowPosition 
+               webScrolledWindowPosition) <- 
+      case statePath of
+        Just path -> readConfigPath path bufferState
+        Nothing   -> return bufferState
+
+  -- Restore feed selected path.
+  feedSelectedPath ?>= \path -> treeViewSetCursor feedView path Nothing
+
+  -- Restore item selected path.
+  itemSelectedPath ?>= \path -> treeViewSetCursor itemView path Nothing
+
+  -- Restore item scroll position.
+  scrolledWindowSetValue itemScrolledWindow itemScrolledWindowPosition
+
+  -- Restore web scroll position.
+  scrolledWindowSetValue webScrolledWindow webScrolledWindowPosition
diff --git a/Manatee/Extension/Reader/Types.hs b/Manatee/Extension/Reader/Types.hs
--- a/Manatee/Extension/Reader/Types.hs
+++ b/Manatee/Extension/Reader/Types.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 import Manatee.Core.Config
 import Manatee.Core.Dynload
 import Manatee.Core.Types
+import Manatee.Toolkit.Cabal.Utils
 import Manatee.Extension.Reader.PageMode
 
 import qualified Data.Map as M
@@ -33,7 +34,7 @@
                                 ["feedInfos"]
              return emptyHookedBuildInfo
          -- Update PageTypeRule after install successful.
-        ,postInst = \ _ _ _ _ -> do
+        ,postInst = \ _ _ pack_des lbi -> do
              (PageTypeRule rule) <- readConfig pageTypeRulePath (PageTypeRule M.empty)
              writeConfig pageTypeRulePath (PageTypeRule (M.insert "PageReader" "manatee-reader" rule))
              -- Update PageModeRule.
@@ -43,5 +44,14 @@
              -- Update ExtensionGloalKeymap.
              (ExtensionGloalKeymap keymap) <- readConfig extensionGlobalKeymapPath (ExtensionGloalKeymap M.empty)
              writeConfig extensionGlobalKeymapPath (ExtensionGloalKeymap
-                                                    (M.insert "F3" ("PageReader", "Feed Reader", []) keymap))
+                                                    (M.insert "F3" ("News Reader",
+                                                                    ("PageReader", "Feed Reader", [])) keymap))
+             -- Update Application info.
+             let snapshotPath = getDataFilePath pack_des lbi "data/welcome/snapshot.png"
+             (WelcomeApplication apps) <- readConfig welcomeApplicationPath (WelcomeApplication M.empty)
+             writeConfig welcomeApplicationPath (WelcomeApplication
+                                                 (M.insert 
+                                                       ("News Reader", snapshotPath)
+                                                       ("PageReader", "Feed Reader", [])
+                                                       apps))
        }
diff --git a/data/welcome/snapshot.png b/data/welcome/snapshot.png
new file mode 100644
Binary files /dev/null and b/data/welcome/snapshot.png differ
diff --git a/manatee-reader.cabal b/manatee-reader.cabal
--- a/manatee-reader.cabal
+++ b/manatee-reader.cabal
@@ -1,9 +1,9 @@
 name:			manatee-reader
-version:		0.0.8
+version:		0.1.0
 Cabal-Version:	>= 1.6
 license:		GPL-3
 license-file:	LICENSE
-copyright:		(c) 2009 ~ 2010 Andy Stewart
+copyright:		(c) 2010 ~ 2011 Andy Stewart
 synopsis:		Feed reader extension for Manatee.
 description:    manatee-reader is feed reader extension for Manatee (Haskell/Gtk+ Integrated Live Environment)
  .
@@ -11,7 +11,7 @@
  .
  Note, you need re-install package to start the configuration file take effect the next time,
  .
- Video at (Select 720p HD) at : <http://www.youtube.com/watch?v=weS6zys3U8k> <http://www.youtube.com/watch?v=A3DgKDVkyeM> <http://v.youku.com/v_show/id_XMjI2MDMzODI4.html>
+ Video (Select 720p HD) at : <http://www.youtube.com/watch?v=weS6zys3U8k> <http://www.youtube.com/watch?v=A3DgKDVkyeM> <http://v.youku.com/v_show/id_XMjI2MDMzODI4.html>
  .
  Screenshots at : <http://goo.gl/MkVw>
  .
@@ -26,19 +26,20 @@
 stability:		provisional
 category:		Manatee, RSS/Atom Reader, Feed, RSS, Atom
 
-tested-with:	GHC==6.12.3
+tested-with:	GHC==7.0.2
 build-type:		Custom
 
 data-dir: ""
 data-files: Config/Reader.hs            
+            data/welcome/snapshot.png
 
 Source-Repository head
   type:         darcs
   location:     http://patch-tag.com/r/AndyStewart/manatee-reader
   
 Library
-     build-depends: base >= 4 && < 5, manatee-core >= 0.0.8, dbus-client >= 0.3 && < 0.4, stm >= 2.1.2.0,
-                    containers >= 0.3.0.0, gtk-serialized-event >= 0.12.0, gtk >= 0.12.0,
+     build-depends: base >= 4 && < 5, manatee-core >= 0.1.0, dbus-client >= 0.3 && < 0.4, stm >= 2.1.2.0,
+                    containers >= 0.3.0.0, gtk >= 0.12.0, derive, binary,
                     text >= 0.7.1.0, webkit >= 0.12.0, feed >= 0.3.7, download-curl >= 0.1.2,
                     utf8-string >= 0.3.4, filepath
      exposed-modules:
