diff --git a/hsdev.cabal b/hsdev.cabal
--- a/hsdev.cabal
+++ b/hsdev.cabal
@@ -1,5 +1,5 @@
 name:                hsdev
-version:             0.3.0.0
+version:             0.3.0.1
 synopsis:            Haskell development library
 description:
   Haskell development library and tool with support of autocompletion, symbol info, go to declaration, find references, hayoo search etc.
@@ -96,6 +96,7 @@
     HsDev.Tools.HDocs
     HsDev.Tools.HLint
     HsDev.Tools.Refact
+    HsDev.Tools.Tabs
     HsDev.Tools.Types
     HsDev.Types
     HsDev.Util
diff --git a/src/HsDev/Client/Commands.hs b/src/HsDev/Client/Commands.hs
--- a/src/HsDev/Client/Commands.hs
+++ b/src/HsDev/Client/Commands.hs
@@ -20,7 +20,7 @@
 import Data.Maybe
 import qualified Data.Map.Strict as M
 import Data.Text (Text, pack, unpack)
-import qualified Data.Text as T (append)
+import qualified Data.Text as T (append, null)
 import System.Directory
 import System.FilePath
 import qualified System.Log.Simple as Log
@@ -292,20 +292,46 @@
 			"s.name like ? escape '\\'"])
 		(fpath ^. path, likePattern sq)
 	return [ScopeSymbol q s | (s :. Only q) <- rs]
-runCommand (FindUsages nm) = toValue $ do
-	let
-		q = nameModule $ toName nm
-		ident = nameIdent $ toName nm
-	query @_ @SymbolUsage (toQuery $ qSymbol `mappend` qModuleId `mappend` select_
+runCommand (FindUsages l c fpath) = toValue $ do
+	us <- query @_ @SymbolUsage (toQuery $ qSymbol `mappend` qModuleId `mappend` select_
 		["n.line", "n.column"]
-		["names as n"]
+		["names as n", "projects_modules_scope as ps", "names as defn", "modules as srcm"]
 		[
-			"m.name == n.resolved_module",
-			"s.name == n.resolved_name",
-			"mu.id == n.module_id",
-			"n.resolved_module == ? or ? is null",
-			"n.resolved_name == ?"])
-		(q, q, ident)
+			"n.module_id = mu.id",
+			"n.resolved_module = defn.resolved_module",
+			"n.resolved_name = defn.resolved_name",
+			"s.name = defn.resolved_name",
+			-- "s.module_id = m.id",
+			"m.name = defn.resolved_module",
+			"(m.id = srcm.id or m.id = ps.module_id)",
+			"(((ps.cabal is null) and (srcm.cabal is null)) or (ps.cabal = srcm.cabal))",
+			"defn.module_id = srcm.id",
+			"(?, ?) between (defn.line, defn.column) and (defn.line_to, defn.column_to)",
+			"(mu.cabal = srcm.cabal or mu.id = srcm.cabal)",
+			"srcm.file = ?"])
+		(l, c, fpath ^. path)
+	locals <- do
+		defs <- query @_ @(ModuleId :. Only Text :. Position :. Only (Maybe Text) :. Position) (toQuery $ qModuleId `mappend` select_
+			["n.name", "n.def_line", "n.def_column", "n.inferred_type", "n.line", "n.column"]
+			["names as n", "names as defn"]
+			[
+				"n.module_id = mu.id",
+				"n.def_line = defn.def_line",
+				"n.def_column = defn.def_column",
+				"defn.module_id = mu.id",
+				"(?, ?) between (defn.line, defn.column) and (defn.line_to, defn.column_to)",
+				"mu.file = ?"])
+			(l, c, fpath ^. path)
+		return $ do
+			(mid :. Only nm :. defPos :. Only ftype :. usePos) <- defs
+			let
+				sym = Symbol {
+					_symbolId = SymbolId nm mid,
+					_symbolDocs = Nothing,
+					_symbolPosition = Just defPos,
+					_symbolInfo = Function ftype }
+			return $ SymbolUsage sym mid usePos
+	return $ us ++ locals
 runCommand (Complete input True fpath) = toValue $
 	query @_ @Symbol (toQuery $ qSymbol `mappend` select_ []
 		["modules as srcm"]
@@ -463,12 +489,10 @@
 	inSessionGhc $ do
 		ms <- findSessionBy (const True)
 		forM_ ms $ \s -> do
-			Log.sendLog Log.Trace $ "stopping session: {}" ~~ s
-			deleteSession s
+			Log.sendLog Log.Trace $ "stopping session: {}" ~~ view sessionKey s
+			deleteSession $ view sessionKey s
 runCommand Exit = toValue serverExit
 
--- TODO: Implement `targetFilter` for sql
-
 targetFilter :: Text -> Maybe Text -> TargetFilter -> (Text, [NamedParam])
 targetFilter mtable _ (TargetProject proj) = (
 	"{t}.cabal in (select cabal from projects where name == :project or cabal == :project)" ~~ ("t" ~% mtable),
@@ -480,7 +504,16 @@
 		~~ ("t" ~% mtable)
 		~~ ("s" ~% stable),
 	[":module_name" := nm])
-targetFilter mtable _ (TargetPackage nm) = ("{t}.package_name == :package_name" ~~ ("t" ~% mtable), [":package_name" := nm])
+targetFilter mtable _ (TargetPackage p) = (tpl ~~ ("t" ~% mtable), params) where
+	pkg = fromMaybe (mkPackage p) (readMaybe (unpack p))
+	tpl
+		| T.null (pkg ^. packageVersion) = "{t}.package_name == :package_name"
+		| otherwise = "{t}.package_name == :package_name and {t}.package_version == :package_version"
+	params
+		| T.null (pkg ^. packageVersion) = [pname]
+		| otherwise = [pname, pver]
+	pname = ":package_name" := (pkg ^. packageName)
+	pver = ":package_version" := (pkg ^. packageVersion)
 targetFilter mtable _ TargetInstalled = ("{t}.package_name is not null" ~~ ("t" ~% mtable), [])
 targetFilter mtable _ TargetSourced = ("{t}.file is not null" ~~ ("t" ~% mtable), [])
 targetFilter mtable _ TargetStandalone = ("{t}.file is not null and {t}.cabal is null" ~~ ("t" ~% mtable), [])
@@ -570,7 +603,8 @@
 						then return m
 						else do
 							defs <- askSession sessionDefines
-							p' <- liftIO $ preload (m ^. moduleId . moduleName) defs [] (m ^. moduleId . moduleLocation) Nothing
+							mcts <- fmap (fmap snd) $ getFileContents fpath'
+							p' <- liftIO $ preload (m ^. moduleId . moduleName) defs [] (m ^. moduleId . moduleLocation) mcts
 							return $ set moduleImports (p' ^. asModule . moduleImports) m
 				Just cabal' -> do
 					proj' <- SQLite.loadProject cabal'
diff --git a/src/HsDev/Database/SQLite.hs b/src/HsDev/Database/SQLite.hs
--- a/src/HsDev/Database/SQLite.hs
+++ b/src/HsDev/Database/SQLite.hs
@@ -45,6 +45,7 @@
 import Distribution.Text (display)
 import Language.Haskell.Exts.Syntax hiding (Name, Module)
 import Language.Haskell.Extension ()
+import System.Directory
 import System.Log.Simple
 import Text.Format
 
@@ -77,13 +78,20 @@
 			[Only equalVersion] <- SQL.query conn "select sum(json(value) == json(?)) > 0 from hsdev where option == 'version';" (Only $ toJSON version)
 			return equalVersion
 		else return True
-	unless goodVersion $
-		-- TODO: Completely drop schema to reinitialize
-		hsdevError $ OtherError "Not implemented: dropping schema of db"
-	when (not hasTables || not goodVersion) $ SQL.withTransaction conn $ do
-		mapM_ (SQL.execute_ conn) commands
-		SQL.execute @(Text, Value) conn "insert into hsdev values (?, ?);" ("version", toJSON version)
-	return conn
+	let
+		start
+			| not goodVersion = do
+					close conn
+					removeFile p
+					conn' <- open p
+					initDb conn'
+			| not hasTables = initDb conn
+			| otherwise = return conn
+		initDb conn' = SQL.withTransaction conn' $ do
+			mapM_ (SQL.execute_ conn) commands
+			SQL.execute @(Text, Value) conn' "insert into hsdev values (?, ?);" ("version", toJSON version)
+			return conn'
+	start
 
 purge :: SessionMonad m => m ()
 purge = do
diff --git a/src/HsDev/Database/Update.hs b/src/HsDev/Database/Update.hs
--- a/src/HsDev/Database/Update.hs
+++ b/src/HsDev/Database/Update.hs
@@ -478,10 +478,10 @@
 			m' <- mapMOf (moduleId . moduleLocation . moduleProject . _Just) refineProjectInfo m
 			Log.sendLog Log.Trace $ "Scanning docs for {}" ~~ view (moduleId . moduleLocation) m'
 			docsMap <- inSessionGhc $ do
-				opts' <- getModuleOpts [] m'
+				(pdbs, opts') <- getModuleOpts [] m'
 				currentSession >>= maybe (return ()) (const clearTargets)
 				-- Calling haddock with targets set sometimes cause errors
-				haddockSession opts'
+				haddockSession pdbs opts'
 				readModuleDocs opts' m'
 			sendUpdateAction $ do
 				SQLite.executeMany "update symbols set docs = ? where name == ? and module_id == ?;"
@@ -512,8 +512,7 @@
 
 		mcts <- fmap (fmap snd) $ S.getFileContents (m' ^?! moduleId . moduleLocation . moduleFile)
 		types' <- inSessionGhc $ do
-			opts' <- getModuleOpts [] m'
-			targetSession opts' m'
+			targetSession [] m'
 			fileTypes m' mcts
 
 		setModTypes (m' ^. moduleId) types'
diff --git a/src/HsDev/Display.hs b/src/HsDev/Display.hs
--- a/src/HsDev/Display.hs
+++ b/src/HsDev/Display.hs
@@ -6,54 +6,13 @@
 	) where
 
 import Control.Lens (view)
-import Data.List (intercalate)
-import Data.Text.Lens (unpacked)
 
-import Text.Format
-
 import System.Directory.Paths
-import HsDev.PackageDb
-import HsDev.Project
-import HsDev.Sandbox
-import HsDev.Symbols.Location
-import HsDev.Symbols.Types
 
 class Display a where
 	display :: a -> String
 	displayType :: a -> String
 
-instance Display PackageDb where
-	display GlobalDb = "global-db"
-	display UserDb = "user-db"
-	display (PackageDb p) = "package-db " ++ display p
-	displayType _ = "package-db"
-
-instance Display PackageDbStack where
-	display = intercalate "/" . map display . packageDbs
-	displayType _ = "package-db-stack"
-
-instance Display ModuleLocation where
-	display (FileModule f _) = display f
-	display (InstalledModule _ _ n) = view unpacked n
-	display (OtherLocation s) = view unpacked s
-	display NoLocation = "<no-location>"
-	displayType _ = "module"
-
-instance Display ModuleTag where
-	display InferredTypesTag = "types"
-	display RefinedDocsTag = "docs"
-	display OnlyHeaderTag = "header"
-	displayType _ = "module-tag"
-
-instance Display Project where
-	display = view (projectName . unpacked)
-	displayType _ = "project"
-
-instance Display Sandbox where
-	display (Sandbox _ fpath) = display fpath
-	displayType (Sandbox CabalSandbox _) = "cabal-sandbox"
-	displayType (Sandbox StackWork _) = "stack-work"
-
 instance Display FilePath where
 	display = id
 	displayType _ = "path"
@@ -61,18 +20,3 @@
 instance Display Path where
 	display = view path
 	displayType _ = "path"
-
-instance Formattable PackageDb where
-	formattable = formattable . display
-
-instance Formattable PackageDbStack where
-	formattable = formattable . display
-
-instance Formattable ModuleLocation where
-	formattable = formattable . display
-
-instance Formattable Project where
-	formattable = formattable . display
-
-instance Formattable Sandbox where
-	formattable = formattable . display
diff --git a/src/HsDev/Inspect.hs b/src/HsDev/Inspect.hs
--- a/src/HsDev/Inspect.hs
+++ b/src/HsDev/Inspect.hs
@@ -48,6 +48,7 @@
 
 import HsDev.Display ()
 import HsDev.Error
+import HsDev.Sandbox (searchPackageDbStack)
 import HsDev.Symbols
 import HsDev.Symbols.Name (fromModuleName_)
 import HsDev.Symbols.Resolve (refineSymbol, refineTable, RefineTable, symbolUniqId)
@@ -319,9 +320,13 @@
 inspectDocs opts m = do
 	let
 		hdocsWorkaround = False
+	pdbs <- case view (moduleId . moduleLocation) m of
+		FileModule fpath _ -> searchPackageDbStack fpath
+		InstalledModule _ _ _ -> return userDb
+		_ -> return userDb
 	docsMap <- if hdocsWorkaround
 		then liftIO $ hdocsProcess (fromMaybe (T.unpack $ view (moduleId . moduleName) m) (preview (moduleId . moduleLocation . moduleFile . path) m)) opts
-		else liftM Just $ hdocs (view (moduleId . moduleLocation) m) opts
+		else liftM Just $ hdocs pdbs (view (moduleId . moduleLocation) m) opts
 	return $ maybe id addDocs docsMap m
 
 -- | Like @inspectDocs@, but in @Ghc@ monad
diff --git a/src/HsDev/PackageDb/Types.hs b/src/HsDev/PackageDb/Types.hs
--- a/src/HsDev/PackageDb/Types.hs
+++ b/src/HsDev/PackageDb/Types.hs
@@ -14,11 +14,13 @@
 import Control.Lens (makeLenses, each, (^.))
 import Control.DeepSeq (NFData(..))
 import Data.Aeson
-import Data.List (tails, isSuffixOf)
+import Data.List (tails, isSuffixOf, intercalate)
 import qualified Data.Text as T
 import Data.String
+import Text.Format
 
 import System.Directory.Paths
+import HsDev.Display
 
 data PackageDb = GlobalDb | UserDb | PackageDb { _packageDb :: Path } deriving (Eq, Ord)
 
@@ -34,6 +36,15 @@
 	show UserDb = "user-db"
 	show (PackageDb p) = "package-db:" ++ p ^. path
 
+instance Display PackageDb where
+	display GlobalDb = "global-db"
+	display UserDb = "user-db"
+	display (PackageDb p) = "package-db " ++ display p
+	displayType _ = "package-db"
+
+instance Formattable PackageDb where
+	formattable = formattable . display
+
 instance ToJSON PackageDb where
 	toJSON GlobalDb = "global-db"
 	toJSON UserDb = "user-db"
@@ -59,6 +70,13 @@
 
 instance NFData PackageDbStack where
 	rnf (PackageDbStack ps) = rnf ps
+
+instance Display PackageDbStack where
+	display = intercalate "/" . map display . packageDbs
+	displayType _ = "package-db-stack"
+
+instance Formattable PackageDbStack where
+	formattable = formattable . display
 
 instance ToJSON PackageDbStack where
 	toJSON (PackageDbStack ps) = toJSON ps
diff --git a/src/HsDev/Project/Types.hs b/src/HsDev/Project/Types.hs
--- a/src/HsDev/Project/Types.hs
+++ b/src/HsDev/Project/Types.hs
@@ -20,11 +20,13 @@
 import Data.Ord
 import Data.Text (Text)
 import qualified Data.Text as T
-import Distribution.Text (display)
+import qualified Distribution.Text as D (display)
 import Language.Haskell.Extension
 import System.FilePath
+import Text.Format
 
 import System.Directory.Paths
+import HsDev.Display
 import HsDev.Util
 
 -- | Cabal project
@@ -50,6 +52,13 @@
 		"\tcabal: " ++ _projectCabal p ^. path,
 		"\tdescription:"] ++ concatMap (map (tab 2) . lines . show) (maybeToList $ _projectDescription p)
 
+instance Display Project where
+	display = T.unpack . _projectName
+	displayType _ = "project"
+
+instance Formattable Project where
+	formattable = formattable . display
+
 instance ToJSON Project where
 	toJSON p = object [
 		"name" .= _projectName p,
@@ -249,10 +258,10 @@
 
 instance Show Info where
 	show i = unlines $ lang ++ exts ++ opts ++ sources ++ otherMods where
-		lang = maybe [] (\l -> ["default-language: " ++ display l]) $ _infoLanguage i
+		lang = maybe [] (\l -> ["default-language: " ++ D.display l]) $ _infoLanguage i
 		exts
 			| null (_infoExtensions i) = []
-			| otherwise = "extensions:" : map (tab 1 . display) (_infoExtensions i)
+			| otherwise = "extensions:" : map (tab 1 . D.display) (_infoExtensions i)
 		opts
 			| null (_infoGHCOptions i) = []
 			| otherwise = "ghc-options:" : map (tab 1 . T.unpack) (_infoGHCOptions i)
@@ -278,13 +287,13 @@
 		v .:: "other-modules"
 
 instance ToJSON Language where
-	toJSON = toJSON . display
+	toJSON = toJSON . D.display
 
 instance FromJSON Language where
 	parseJSON = withText "language" $ \txt -> parseDT "Language" (T.unpack txt)
 
 instance ToJSON Extension where
-	toJSON = toJSON . display
+	toJSON = toJSON . D.display
 
 instance FromJSON Extension where
 	parseJSON = withText "extension" $ \txt -> parseDT "Extension" (T.unpack txt)
diff --git a/src/HsDev/Sandbox.hs b/src/HsDev/Sandbox.hs
--- a/src/HsDev/Sandbox.hs
+++ b/src/HsDev/Sandbox.hs
@@ -30,8 +30,10 @@
 import qualified Distribution.Text as T (display)
 import System.FilePath
 import System.Log.Simple (MonadLog(..))
+import Text.Format
 
 import System.Directory.Paths
+import HsDev.Display
 import HsDev.PackageDb
 import HsDev.Project.Types
 import HsDev.Scan.Browse (browsePackages)
@@ -61,6 +63,14 @@
 instance Show Sandbox where
 	show (Sandbox _ p) = T.unpack p
 
+instance Display Sandbox where
+	display (Sandbox _ fpath) = display fpath
+	displayType (Sandbox CabalSandbox _) = "cabal-sandbox"
+	displayType (Sandbox StackWork _) = "stack-work"
+
+instance Formattable Sandbox where
+	formattable = formattable . display
+
 instance ToJSON Sandbox where
 	toJSON (Sandbox _ p) = toJSON p
 
@@ -138,7 +148,7 @@
 -- | Get actual sandbox build path: <arch>-<platform>-<compiler>-<version>
 cabalSandboxLib :: GhcM FilePath
 cabalSandboxLib = do
-	tmpSession ["-no-user-package-db"]
+	tmpSession globalDb ["-no-user-package-db"]
 	df <- GHC.getSessionDynFlags
 	let
 		res =
@@ -154,27 +164,25 @@
 cabalSandboxPackageDb = liftM (++ "-packages.conf.d") cabalSandboxLib
 
 -- | Options for GHC for module and project
-getModuleOpts :: [String] -> Module -> GhcM [String]
+getModuleOpts :: [String] -> Module -> GhcM (PackageDbStack, [String])
 getModuleOpts opts m = do
 	pdbs <- case view (moduleId . moduleLocation) m of
 		FileModule fpath _ -> searchPackageDbStack fpath
 		InstalledModule _ _ _ -> return userDb
 		_ -> return userDb
 	pkgs <- browsePackages opts pdbs
-	return $ concat [
-		packageDbStackOpts pdbs,
+	return $ (pdbs, concat [
 		moduleOpts pkgs m,
-		opts]
+		opts])
 
 -- | Options for GHC for project target
-getProjectTargetOpts :: [String] -> Project -> Info -> GhcM [String]
+getProjectTargetOpts :: [String] -> Project -> Info -> GhcM (PackageDbStack, [String])
 getProjectTargetOpts opts proj t = do
 	pdbs <- searchPackageDbStack $ view projectPath proj
 	pkgs <- browsePackages opts pdbs
-	return $ concat [
-		packageDbStackOpts pdbs,
+	return $ (pdbs, concat [
 		projectTargetOpts pkgs proj t,
-		opts]
+		opts])
 
 -- | Get sandbox of project (if any)
 getProjectSandbox :: MonadLog m => Project -> m (Maybe Sandbox)
diff --git a/src/HsDev/Scan.hs b/src/HsDev/Scan.hs
--- a/src/HsDev/Scan.hs
+++ b/src/HsDev/Scan.hs
@@ -40,7 +40,7 @@
 import qualified HsDev.Database.SQLite as SQLite
 import HsDev.Database.SQLite.Select
 import HsDev.Scan.Browse (browsePackages)
-import HsDev.Server.Types (FileSource(..), SessionMonad(..), CommandMonad(..), inSessionGhc)
+import HsDev.Server.Types (FileSource(..), SessionMonad(..), CommandMonad(..), inSessionGhc, postSessionUpdater)
 import HsDev.Sandbox
 import HsDev.Symbols
 import HsDev.Symbols.Types
@@ -247,5 +247,5 @@
 			if fmtime < tm'
 				then return (Just (tm', cts))
 				else do
-					SQLite.execute "delete from file_contents where file = ?;" (SQLite.Only fpath)
+					void $ postSessionUpdater $ SQLite.execute "delete from file_contents where file = ?;" (SQLite.Only fpath)
 					return Nothing
diff --git a/src/HsDev/Scan/Browse.hs b/src/HsDev/Scan/Browse.hs
--- a/src/HsDev/Scan/Browse.hs
+++ b/src/HsDev/Scan/Browse.hs
@@ -55,13 +55,13 @@
 -- | Browse packages
 browsePackages :: [String] -> PackageDbStack -> GhcM [PackageConfig]
 browsePackages opts dbs = do
-	tmpSession (packageDbStackOpts dbs ++ opts)
+	tmpSession dbs opts
 	liftM (map readPackageConfig) packageConfigs
 
 -- | Get packages with deps
 browsePackagesDeps :: [String] -> PackageDbStack -> GhcM (Deps PackageConfig)
 browsePackagesDeps opts dbs = do
-	tmpSession (packageDbStackOpts dbs ++ opts)
+	tmpSession dbs opts
 	df <- GHC.getSessionDynFlags
 	cfgs <- packageConfigs
 	return $ mapDeps (toPkg df) $ mconcat [deps (Compat.unitId cfg) (Compat.depends df cfg) | cfg <- cfgs]
@@ -73,7 +73,7 @@
 -- otherwise hidden packages won't be loaded
 listModules :: [String] -> PackageDbStack -> [ModulePackage] -> GhcM [ModuleLocation]
 listModules opts dbs pkgs = do
-	tmpSession (packageDbStackOpts dbs ++ opts ++ packagesOpts)
+	tmpSession dbs (opts ++ packagesOpts)
 	ms <- packageDbModules
 	return [ghcModuleLocation p m | (p, m) <- ms]
 	where
@@ -84,7 +84,7 @@
 -- one of them can be lookuped and therefore modules from different version packages won't be actually inspected
 browseModules :: [String] -> PackageDbStack -> [ModuleLocation] -> GhcM [InspectedModule]
 browseModules opts dbs mlocs = do
-	tmpSession (packageDbStackOpts dbs ++ opts)
+	tmpSession dbs opts
 	liftM concat . withEachPackage (const $ browseModules' opts) $ mlocs
 
 -- | Inspect installed modules, doesn't set session and package flags!
diff --git a/src/HsDev/Server/Base.hs b/src/HsDev/Server/Base.hs
--- a/src/HsDev/Server/Base.hs
+++ b/src/HsDev/Server/Base.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, OverloadedStrings, CPP, PatternGuards #-}
+{-# LANGUAGE CPP, OverloadedStrings, CPP, PatternGuards, TypeApplications #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 module HsDev.Server.Base (
@@ -54,7 +54,7 @@
 import HsDev.Error
 import qualified HsDev.Database.Update as Update
 import HsDev.Inspect (getDefines)
-import HsDev.Tools.Ghc.Worker
+import HsDev.Tools.Ghc.Worker hiding (Session)
 import HsDev.Server.Types
 import HsDev.Server.Message
 import HsDev.Symbols.Location (ModuleLocation(..))
@@ -95,15 +95,20 @@
 
 	session <- liftIO $ fixIO $ \sess -> do
 		let
-			setFileCts fpath Nothing = withSession sess $ do
+			setFileCts fpath Nothing = void $ withSession sess $ postSessionUpdater $ do
 				Log.sendLog Log.Trace $ "dropping file contents for {}" ~~ fpath
 				SQLite.execute "delete from file_contents where file = ?;" (SQLite.Only fpath)
 			setFileCts fpath (Just cts) = do
 				tm <- getPOSIXTime
 				withSession sess $ do
-					Log.sendLog Log.Trace $ "setting file contents for {} with mtime = {}" ~~ fpath ~~ show tm
-					SQLite.execute "insert or replace into file_contents (file, contents, mtime) values (?, ?, ?);" (fpath, cts, (fromRational (toRational tm) :: Double))
-				writeChan (W.watcherChan watcher) (W.WatchedModule, W.Event W.Modified (view path fpath) tm)
+					notChanged <- SQLite.query @_ @(SQLite.Only Bool) "select contents == ? from file_contents where file = ?;" (cts, fpath)
+					let
+						notChanged' = any SQLite.fromOnly notChanged
+					void $ postSessionUpdater $ do
+						Log.sendLog Log.Trace $ "setting file contents for {} with mtime = {}" ~~ fpath ~~ show tm
+						SQLite.execute "insert or replace into file_contents (file, contents, mtime) values (?, ?, ?);" (fpath, cts, (fromRational (toRational tm) :: Double))
+						unless notChanged' $ liftIO $
+							writeChan (W.watcherChan watcher) (W.WatchedModule, W.Event W.Modified (view path fpath) tm)
 
 		uw <- startWorker (withSession sess . withSqlConnection) id logAll
 
diff --git a/src/HsDev/Server/Types.hs b/src/HsDev/Server/Types.hs
--- a/src/HsDev/Server/Types.hs
+++ b/src/HsDev/Server/Types.hs
@@ -6,7 +6,8 @@
 	SessionLog(..), Session(..), SessionMonad(..), askSession, ServerM(..),
 	CommandOptions(..), CommandMonad(..), askOptions, ClientM(..),
 	withSession, serverListen, serverSetLogLevel, serverWait, serverWaitClients,
-	serverSqlDatabase, openSqlConnection, closeSqlConnection, withSqlConnection, withSqlTransaction, serverSetFileContents, inSessionGhc, inSessionUpdater, serverExit, commandRoot, commandNotify, commandLink, commandHold,
+	serverSqlDatabase, openSqlConnection, closeSqlConnection, withSqlConnection, withSqlTransaction, serverSetFileContents,
+	inSessionGhc, inSessionUpdater, postSessionUpdater, serverExit, commandRoot, commandNotify, commandLink, commandHold,
 	ServerCommand(..), ConnectionPort(..), ServerOpts(..), silentOpts, ClientOpts(..), serverOptsArgs, Request(..),
 
 	Command(..),
@@ -15,6 +16,7 @@
 	) where
 
 import Control.Applicative
+import Control.Concurrent.Async (Async)
 import qualified Control.Concurrent.FiniteChan as F
 import Control.Lens (view, set)
 import Control.Monad.Base
@@ -240,6 +242,12 @@
 	uw <- askSession sessionUpdater
 	inWorkerWith (hsdevError . OtherError . displayException) uw act
 
+-- | Post to updater and return
+postSessionUpdater :: SessionMonad m => ServerM IO a -> m (Async a)
+postSessionUpdater act = do
+	uw <- askSession sessionUpdater
+	liftIO $ sendTask uw act
+
 -- | Exit session
 serverExit :: SessionMonad m => m ()
 serverExit = join . liftM liftIO $ askSession sessionExit
@@ -437,7 +445,7 @@
 	Whoat Int Int Path |
 	ResolveScopeModules SearchQuery Path |
 	ResolveScope SearchQuery Path |
-	FindUsages Text |
+	FindUsages Int Int Path |
 	Complete Text Bool Path |
 	Hayoo {
 		hayooQuery :: String,
@@ -508,7 +516,7 @@
 	paths f (Whoat l c fpath) = Whoat <$> pure l <*> pure c <*> paths f fpath
 	paths f (ResolveScopeModules q fpath) = ResolveScopeModules q <$> paths f fpath
 	paths f (ResolveScope q fpath) = ResolveScope q <$> paths f fpath
-	paths _ (FindUsages nm) = pure $ FindUsages nm
+	paths f (FindUsages l c fpath) = FindUsages <$> pure l <*> pure c <*> paths f fpath
 	paths f (Complete n g fpath) = Complete n g <$> paths f fpath
 	paths f (UnresolvedSymbols fs) = UnresolvedSymbols <$> traverse (paths f) fs
 	paths f (Lint fs) = Lint <$> traverse (paths f) fs
@@ -562,7 +570,7 @@
 		cmd "scope" "get declarations accessible from module or within a project" (
 			subparser (cmd "modules" "get modules accessible from module or within a project" (ResolveScopeModules <$> cmdP <*> ctx)) <|>
 			ResolveScope <$> cmdP <*> ctx),
-		cmd "usages" "find usages of fully qualified symbol (qualified with module its defined in)" (FindUsages <$> textArgument idm),
+		cmd "usages" "find usages of symbol within project/module" (FindUsages <$> argument auto (metavar "line") <*> argument auto (metavar "column") <*> ctx),
 		cmd "complete" "show completions for input" (Complete <$> textArgument idm <*> wideFlag <*> ctx),
 		cmd "hayoo" "find declarations online via Hayoo" (Hayoo <$> strArgument idm <*> hayooPageArg <*> hayooPagesArg),
 		cmd "cabal" "cabal commands" (subparser $ cmd "list" "list cabal packages" (CabalList <$> many (textArgument idm))),
@@ -687,7 +695,7 @@
 	toJSON (Whoat l c f) = cmdJson "whoat" ["line" .= l, "column" .= c, "file" .= f]
 	toJSON (ResolveScopeModules q f) = cmdJson "scope modules" ["query" .= q, "file" .= f]
 	toJSON (ResolveScope q f) = cmdJson "scope" ["query" .= q, "file" .= f]
-	toJSON (FindUsages nm) = cmdJson "usages" ["name" .= nm]
+	toJSON (FindUsages l c f) = cmdJson "usages" ["line" .= l, "column" .= c, "file" .= f]
 	toJSON (Complete q w f) = cmdJson "complete" ["prefix" .= q, "wide" .= w, "file" .= f]
 	toJSON (Hayoo q p ps) = cmdJson "hayoo" ["query" .= q, "page" .= p, "pages" .= ps]
 	toJSON (CabalList ps) = cmdJson "cabal list" ["packages" .= ps]
@@ -741,7 +749,7 @@
 		guardCmd "whoat" v *> (Whoat <$> v .:: "line" <*> v .:: "column" <*> v .:: "file"),
 		guardCmd "scope modules" v *> (ResolveScopeModules <$> v .:: "query" <*> v .:: "file"),
 		guardCmd "scope" v *> (ResolveScope <$> v .:: "query" <*> v .:: "file"),
-		guardCmd "usages" v *> (FindUsages <$> v .:: "name"),
+		guardCmd "usages" v *> (FindUsages <$> v .:: "line" <*> v .:: "column" <*> v .:: "file"),
 		guardCmd "complete" v *> (Complete <$> v .:: "prefix" <*> (v .:: "wide" <|> pure False) <*> v .:: "file"),
 		guardCmd "hayoo" v *> (Hayoo <$> v .:: "query" <*> (v .:: "page" <|> pure 0) <*> (v .:: "pages" <|> pure 1)),
 		guardCmd "cabal list" v *> (CabalList <$> v .::?! "packages"),
@@ -770,7 +778,7 @@
 	toJSON (TargetProject pname) = object ["project" .= pname]
 	toJSON (TargetFile fpath) = object ["file" .= fpath]
 	toJSON (TargetModule mname) = object ["module" .= mname]
-	toJSON (TargetPackage pname) = object ["package" .= pname]
+	toJSON (TargetPackage pkg) = object ["package" .= pkg]
 	toJSON TargetInstalled = toJSON ("installed" :: String)
 	toJSON TargetSourced = toJSON ("sourced" :: String)
 	toJSON TargetStandalone = toJSON ("standalone" :: String)
diff --git a/src/HsDev/Stack.hs b/src/HsDev/Stack.hs
--- a/src/HsDev/Stack.hs
+++ b/src/HsDev/Stack.hs
@@ -43,7 +43,7 @@
 -- | Get compiler version
 stackCompiler :: GhcM String
 stackCompiler = do
-	tmpSession ["-no-user-package-db"]
+	tmpSession globalDb ["-no-user-package-db"]
 	df <- GHC.getSessionDynFlags
 	let
 		res =
diff --git a/src/HsDev/Symbols/Location.hs b/src/HsDev/Symbols/Location.hs
--- a/src/HsDev/Symbols/Location.hs
+++ b/src/HsDev/Symbols/Location.hs
@@ -30,11 +30,14 @@
 import Data.List (findIndex)
 import Data.Maybe
 import Data.Text (Text, pack, unpack)
+import Data.Text.Lens (unpacked)
 import qualified Data.Text as T
 import System.FilePath
 import Text.Read (readMaybe)
+import Text.Format
 
 import System.Directory.Paths
+import HsDev.Display
 import HsDev.PackageDb.Types
 import HsDev.Project.Types
 import HsDev.Util ((.::), (.::?), (.::?!), objectUnion, noNulls)
@@ -140,6 +143,16 @@
 
 instance Show ModuleLocation where
 	show = unpack . locationId
+
+instance Display ModuleLocation where
+	display (FileModule f _) = display f
+	display (InstalledModule _ _ n) = view unpacked n
+	display (OtherLocation s) = view unpacked s
+	display NoLocation = "<no-location>"
+	displayType _ = "module"
+
+instance Formattable ModuleLocation where
+	formattable = formattable . display
 
 instance ToJSON ModuleLocation where
 	toJSON (FileModule f p) = object $ noNulls ["file" .= f, "project" .= fmap (view projectCabal) p]
diff --git a/src/HsDev/Symbols/Types.hs b/src/HsDev/Symbols/Types.hs
--- a/src/HsDev/Symbols/Types.hs
+++ b/src/HsDev/Symbols/Types.hs
@@ -43,6 +43,7 @@
 import Text.Format
 
 import Control.Apply.Util (chain)
+import HsDev.Display
 import HsDev.PackageDb.Types
 import HsDev.Project
 import HsDev.Symbols.Name
@@ -436,6 +437,12 @@
 	rnf InferredTypesTag = ()
 	rnf RefinedDocsTag = ()
 	rnf OnlyHeaderTag = ()
+
+instance Display ModuleTag where
+	display InferredTypesTag = "types"
+	display RefinedDocsTag = "docs"
+	display OnlyHeaderTag = "header"
+	displayType _ = "module-tag"
 
 instance ToJSON ModuleTag where
 	toJSON InferredTypesTag = toJSON ("types" :: String)
diff --git a/src/HsDev/Tools/Ghc/Check.hs b/src/HsDev/Tools/Ghc/Check.hs
--- a/src/HsDev/Tools/Ghc/Check.hs
+++ b/src/HsDev/Tools/Ghc/Check.hs
@@ -8,18 +8,16 @@
 	module HsDev.Symbols.Types,
 	PackageDb(..), PackageDbStack(..), Project(..),
 
-	recalcNotesTabs,
-
 	module Control.Monad.Except
 	) where
 
-import Control.Lens (preview, view, each, (^..), (^.))
+import Control.Lens (view, (^.))
 import Control.Monad.Except
-import Data.Maybe (fromMaybe)
+import qualified Data.Map as M
 import Data.Text (Text)
 import System.Log.Simple (MonadLog(..), scope, sendLog, Level(Trace))
 
-import GHC hiding (Warning, Module, moduleName)
+import GHC hiding (Warning, Module)
 
 import Control.Concurrent.FiniteChan
 import HsDev.Error
@@ -30,7 +28,7 @@
 import HsDev.Tools.Ghc.Worker
 import HsDev.Tools.Ghc.Compat as C
 import HsDev.Tools.Types
-import HsDev.Util (readFileUtf8, ordNub)
+import HsDev.Tools.Tabs
 import System.Directory.Paths
 
 -- | Check module source
@@ -40,6 +38,9 @@
 		ch <- liftIO newChan
 		let
 			dir = sourceRoot_ (m ^. moduleId)
+			-- FIXME: There can be dependent modules with modified file contents
+			-- Their contents should be set here too
+			srcs = maybe mempty (M.singleton file) msrc
 		ex <- liftIO $ dirExists dir
 		sendLog Trace "loading targets"
 		withFlags $ (if ex then withCurrentDirectory (dir ^. path) else id) $ do
@@ -48,18 +49,5 @@
 			loadTargets [target]
 		notes <- liftIO $ stopChan ch
 		sendLog Trace "targets checked"
-		liftIO $ recalcNotesTabs notes
+		liftIO $ recalcNotesTabs srcs notes
 	_ -> scope "check" $ hsdevError $ ModuleNotSource (view (moduleId . moduleLocation) m)
-
--- Recalc tabs for notes
-recalcNotesTabs :: [Note OutputMessage] -> IO [Note OutputMessage]
-recalcNotesTabs notes = do
-	cts <- mapM (readFileUtf8 . view path) files
-	let
-		recalc' n = fromMaybe n $ do
-			fname <- preview (noteSource . moduleFile) n
-			cts' <- lookup fname (zip files cts)
-			return $ recalcTabs cts' 8 n
-	return $ map recalc' notes
-	where
-		files = ordNub $ notes ^.. each . noteSource . moduleFile
diff --git a/src/HsDev/Tools/Ghc/MGhc.hs b/src/HsDev/Tools/Ghc/MGhc.hs
--- a/src/HsDev/Tools/Ghc/MGhc.hs
+++ b/src/HsDev/Tools/Ghc/MGhc.hs
@@ -2,9 +2,10 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 module HsDev.Tools.Ghc.MGhc (
+	Session(..), sessionKey, sessionData,
 	SessionState(..), sessionActive, sessionMap,
 	MGhcT(..), runMGhcT, liftGhc,
-	currentSession, hasSession, findSession, findSessionBy, saveSession,
+	currentSession, getSessionData, setSessionData, hasSession, findSession, findSessionBy, saveSession,
 	initSession, newSession,
 	switchSession, switchSession_,
 	deleteSession, restoreSession, usingSession, tempSession
@@ -17,7 +18,6 @@
 import Control.Monad.State
 import Data.Default
 import Data.IORef
-import Data.List (find)
 import Data.Map.Strict (Map)
 import qualified Data.Map.Strict as M
 import Data.Maybe (fromMaybe, isJust)
@@ -27,24 +27,40 @@
 import Exception hiding (catch, mask, uninterruptibleMask, bracket, finally)
 import GHC
 import GHCi
-import GhcMonad
+import GhcMonad hiding (Session(..))
+import qualified GhcMonad (Session(..))
 import HscTypes
 import Outputable
 import SysTools
 
-data SessionState s = SessionState {
-	_sessionActive :: Maybe s,
-	_sessionMap :: Map s HscEnv }
+data Session s d = Session {
+	_sessionKey :: s,
+	_sessionData :: d }
+		deriving (Eq, Ord, Read, Show)
 
-instance Default (SessionState s) where
+sessionKey :: Lens' (Session s d) s
+sessionKey = lens g s where
+	g = _sessionKey
+	s sess k = sess { _sessionKey = k }
+
+sessionData :: Lens' (Session s d) d
+sessionData = lens g s where
+	g = _sessionData
+	s sess dat = sess { _sessionData = dat }
+
+data SessionState s d = SessionState {
+	_sessionActive :: Maybe (Session s d),
+	_sessionMap :: Map s (HscEnv, d) }
+
+instance Default (SessionState s d) where
 	def = SessionState Nothing M.empty
 
-sessionActive :: Lens' (SessionState s) (Maybe s)
+sessionActive :: Lens' (SessionState s d) (Maybe (Session s d))
 sessionActive = lens g s where
 	g = _sessionActive
 	s st nm = st { _sessionActive = nm }
 
-sessionMap :: Lens' (SessionState s) (Map s HscEnv)
+sessionMap :: Lens' (SessionState s d) (Map s (HscEnv, d))
 sessionMap = lens g s where
 	g = _sessionMap
 	s st m = st { _sessionMap = m }
@@ -62,8 +78,8 @@
 			act v = ReaderT $ act' . runReaderT v
 
 -- | Multi-session ghc monad
-newtype MGhcT s m a = MGhcT { unMGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s) m)) a }
-	deriving (Functor, Applicative, Monad, MonadIO, ExceptionMonad, HasDynFlags, GhcMonad, MonadState (SessionState s), MonadReader (Maybe FilePath), MonadThrow, MonadCatch, MonadMask, MonadLog)
+newtype MGhcT s d m a = MGhcT { unMGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s d) m)) a }
+	deriving (Functor, Applicative, Monad, MonadIO, ExceptionMonad, HasDynFlags, GhcMonad, MonadState (SessionState s d), MonadReader (Maybe FilePath), MonadThrow, MonadCatch, MonadMask, MonadLog)
 
 instance MonadTrans GhcT where
 	lift = liftGhcT
@@ -93,78 +109,88 @@
 		q g' act = GhcT $ g' . unGhcT act
 
 -- | Run multi-session ghc
-runMGhcT :: (MonadIO m, ExceptionMonad m, Ord s) => Maybe FilePath -> MGhcT s m a -> m a
+runMGhcT :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => Maybe FilePath -> MGhcT s d m a -> m a
 runMGhcT lib act = do
 	ref <- liftIO $ newIORef (panic "empty session")
 	let
-		session = Session ref
+		session = GhcMonad.Session ref
 	flip evalStateT def $ flip runReaderT lib $ flip unGhcT session $ unMGhcT $ act `gfinally` cleanup
 	where
-		cleanup :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m ()
+		cleanup :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => MGhcT s d m ()
 		cleanup = do
 			void saveSession
 			sessions <- gets (M.elems . view sessionMap)
-			liftIO $ mapM_ cleanupSession sessions
+			liftIO $ mapM_ (cleanupSession . view _1) sessions
 			modify (set sessionMap M.empty)
 
 -- | Lift `Ghc` monad onto `MGhc`
-liftGhc :: MonadIO m => Ghc a -> MGhcT s m a
+liftGhc :: MonadIO m => Ghc a -> MGhcT s d m a
 liftGhc (Ghc act) = MGhcT $ GhcT $ liftIO . act
 
-currentSession :: MonadIO m => MGhcT s m (Maybe s)
+-- | Get current session
+currentSession :: MonadIO m => MGhcT s d m (Maybe (Session s d))
 currentSession = gets (view sessionActive)
 
+-- | Get current session data
+getSessionData :: MonadIO m => MGhcT s d m (Maybe d)
+getSessionData = gets (preview (sessionActive . _Just . sessionData))
+
+-- | Set current session data
+setSessionData :: MonadIO m => d -> MGhcT s d m ()
+setSessionData sdata = modify (set (sessionActive . _Just . sessionData) sdata)
+
 -- | Does session exist
-hasSession :: (MonadIO m, Ord s) => s -> MGhcT s m Bool
+hasSession :: (MonadIO m, Ord s) => s -> MGhcT s d m Bool
 hasSession key = do
-	msess <- gets (preview (sessionMap . ix key))
+	msess <- findSession key
 	return $ isJust msess
 
 -- | Find session
-findSession :: (MonadIO m, Ord s) => s -> MGhcT s m (Maybe s)
+findSession :: (MonadIO m, Ord s) => s -> MGhcT s d m (Maybe (Session s d))
 findSession key = do
-	mkeys <- gets (M.keys . view sessionMap)
-	return $ find (== key) mkeys
+	sdata <- gets (preview (sessionMap . ix key . _2))
+	return $ fmap (Session key) sdata
 
 -- | Find session by
-findSessionBy :: MonadIO m => (s -> Bool) -> MGhcT s m [s]
+findSessionBy :: MonadIO m => (s -> Bool) -> MGhcT s d m [Session s d]
 findSessionBy p = do
-	mkeys <- gets (M.keys . view sessionMap)
-	return $ filter p mkeys
+	sessions <- gets (M.toList . view sessionMap)
+	return [Session key sdata | (key, (_, sdata)) <- sessions, p key]
 
 -- | Save current session
-saveSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m (Maybe s)
+saveSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s d m (Maybe (Session s d))
 saveSession = do
-	key <- currentSession
-	case key of
-		Just key' -> do
+	msess <- currentSession
+	case msess of
+		Just (Session key' dat') -> do
 			sess <- getSession
-			modify (set (sessionMap . at key') (Just sess))
+			modify (set (sessionMap . at key') (Just (sess, dat')))
 		Nothing -> return ()
-	return key
+	return msess
 
 -- | Initialize new session
-initSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m ()
+initSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s d m ()
 initSession = do
 	lib <- ask
 	initGhcMonad lib
 	void saveSession
 
-activateSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m (Maybe HscEnv)
+activateSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m (Maybe HscEnv)
 activateSession key = do
 	void saveSession
-	modify (set sessionActive $ Just key)
-	gets (view (sessionMap . at key))
+	sdata <- gets (view (sessionMap . ix key . _2))
+	modify (set sessionActive $ Just (Session key sdata))
+	gets (preview (sessionMap . ix key . _1))
 
 -- | Create new named session, deleting existing session
-newSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m ()
+newSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m ()
 newSession key = do
 	msess <- activateSession key
 	maybe (return ()) (liftIO . cleanupSession) msess
 	initSession
 
 -- | Switch to session, creating if not exist, returns True if session was created
-switchSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m Bool
+switchSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m Bool
 switchSession key = do
 	msess <- activateSession key
 	case msess of
@@ -172,38 +198,38 @@
 		Just sess -> setSession sess >> return False
 
 -- | Switch to session, creating if not exist and initializing with passed function
-switchSession_ :: (MonadIO m, ExceptionMonad m, Ord s) => s -> Maybe (MGhcT s m ()) -> MGhcT s m ()
+switchSession_ :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> Maybe (MGhcT s d m ()) -> MGhcT s d m ()
 switchSession_ key f = do
 	new <- switchSession key
 	when new $ fromMaybe (return ()) f
 
 -- | Delete existing session
-deleteSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m ()
+deleteSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m ()
 deleteSession key = do
 	cur <- saveSession
-	when (cur == Just key) $
+	when (preview (_Just . sessionKey) cur == Just key) $
 		modify (set sessionActive Nothing)
-	msess <- gets (view (sessionMap . at key))
+	msess <- gets (preview (sessionMap . ix key . _1))
 	modify (set (sessionMap . at key) Nothing)
 	case msess of
 		Nothing -> return ()
 		Just sess -> liftIO $ cleanupSession sess
 
 -- | Save and restore session
-restoreSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => MGhcT s m a -> MGhcT s m a
-restoreSession act = bracket saveSession (maybe (return ()) (void . switchSession)) $ const act
+restoreSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => MGhcT s d m a -> MGhcT s d m a
+restoreSession act = bracket saveSession (maybe (return ()) (void . switchSession . view sessionKey)) $ const act
 
 -- | Run action using session, restoring session back
-usingSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => s -> MGhcT s m a -> MGhcT s m a
+usingSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m a -> MGhcT s d m a
 usingSession key act = restoreSession $ do
 	void $ switchSession key
 	act
 
 -- | Run with temporary session, like @usingSession@, but deletes self session
-tempSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => s -> MGhcT s m a -> MGhcT s m a
+tempSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m a -> MGhcT s d m a
 tempSession key act = do
 	exist' <- hasSession key
-	usingSession key act `finally` when (not exist') (deleteSession key)
+	usingSession key act `finally` unless exist' (deleteSession key)
 
 -- | Cleanup session
 cleanupSession :: HscEnv -> IO ()
diff --git a/src/HsDev/Tools/Ghc/Session.hs b/src/HsDev/Tools/Ghc/Session.hs
--- a/src/HsDev/Tools/Ghc/Session.hs
+++ b/src/HsDev/Tools/Ghc/Session.hs
@@ -23,8 +23,8 @@
 -- | Session for module
 targetSession :: [String] -> Module -> GhcM ()
 targetSession opts m = do
-	opts' <- getModuleOpts opts m
-	ghcSession ("-Wall" : opts')
+	(pdbs, opts') <- getModuleOpts opts m
+	ghcSession pdbs ("-Wall" : opts')
 
 -- | Interpret file
 interpretModule :: Module -> Maybe Text -> GhcM ()
diff --git a/src/HsDev/Tools/Ghc/Worker.hs b/src/HsDev/Tools/Ghc/Worker.hs
--- a/src/HsDev/Tools/Ghc/Worker.hs
+++ b/src/HsDev/Tools/Ghc/Worker.hs
@@ -33,6 +33,7 @@
 import Control.Monad.Reader
 import Control.Monad.Catch
 import Data.Dynamic
+import Data.Monoid
 import Data.Time.Clock (getCurrentTime)
 import Data.String (fromString)
 import Data.Text (Text)
@@ -54,13 +55,14 @@
 import Control.Concurrent.Worker
 import System.Directory.Paths
 import HsDev.Symbols.Location (Position(..), Region(..), region, ModuleLocation(..))
+import HsDev.PackageDb.Types
 import HsDev.Tools.Types
 import HsDev.Tools.Ghc.Compat
 import qualified HsDev.Tools.Ghc.Compat as C (setLogAction)
 import HsDev.Tools.Ghc.MGhc
 
 data SessionType = SessionGhci | SessionGhc | SessionHaddock | SessionTmp deriving (Eq, Ord)
-data SessionConfig = SessionConfig SessionType [String] deriving (Eq, Ord)
+data SessionConfig = SessionConfig SessionType PackageDbStack deriving (Eq, Ord)
 
 instance Show SessionType where
 	show SessionGhci = "ghci"
@@ -68,14 +70,16 @@
 	show SessionHaddock = "haddock"
 	show SessionTmp = "tmp"
 
+instance Formattable SessionType
+
 instance Show SessionConfig where
-	show (SessionConfig t opts) = unwords (show t : opts)
+	show (SessionConfig t pdb) = "{} {}" ~~ t ~~ pdb
 
 instance Formattable SessionConfig
 
-type GhcM a = MGhcT SessionConfig (LogT IO) a
+type GhcM a = MGhcT SessionConfig (First DynFlags) (LogT IO) a
 
-type GhcWorker = Worker (MGhcT SessionConfig (LogT IO))
+type GhcWorker = Worker (MGhcT SessionConfig (First DynFlags) (LogT IO))
 
 instance (Monad m, GhcMonad m) => GhcMonad (ReaderT r m) where
 	getSession = lift getSession
@@ -104,38 +108,50 @@
 		logErr e = Log.sendLog Log.Warning ("exception in ghc worker task: {}" ~~ displayException e)
 
 -- | Create session with options
-workerSession :: SessionType -> [String] -> GhcM ()
-workerSession ty opts = do
+workerSession :: SessionType -> PackageDbStack -> [String] -> GhcM ()
+workerSession ty pdbs opts = do
 	ms <- findSessionBy toKill
 	forM_ ms $ \s' -> do
-		Log.sendLog Log.Trace $ "killing session: {}" ~~ s'
-		deleteSession s'
-	Log.sendLog Log.Trace $ "session: {}" ~~ SessionConfig ty opts
-	switchSession_ (SessionConfig ty opts) $ Just initialize
+		Log.sendLog Log.Trace $ "killing session: {}" ~~ view sessionKey s'
+		deleteSession $ view sessionKey s'
+	Log.sendLog Log.Trace $ "session: {}" ~~ SessionConfig ty pdbs
+	switchSession_ (SessionConfig ty pdbs) $ Just initialize
+	setSessionFlags
 	where
-		toKill (SessionConfig ty' opts') = or [
-			(ty == ty' && opts /= opts'),
+		toKill (SessionConfig ty' pdbs') = or [
+			(ty == ty' && pdbs /= pdbs'),
 			(ty /= ty' && ty' `elem` [SessionTmp, SessionHaddock] && ty /= SessionTmp)]
-		initialize = case ty of
-			SessionGhci -> ghcRun opts (importModules preludeModules)
-			SessionGhc -> ghcRun opts (return ())
-			SessionTmp -> ghcRun opts (return ())
-			SessionHaddock -> ghcRunWith noLinkFlags ("-haddock" : opts) (return ())
+		initialize = do
+			run
+			dflags <- getSessionDynFlags
+			setSessionData (First $ Just dflags)
+		run = case ty of
+			SessionGhci -> ghcRun pdbsOpts (importModules preludeModules)
+			SessionGhc -> ghcRun pdbsOpts (return ())
+			SessionTmp -> ghcRun pdbsOpts (return ())
+			SessionHaddock -> ghcRunWith noLinkFlags ("-haddock" : pdbsOpts) (return ())
+		setSessionFlags = do
+			Log.sendLog Log.Trace $ "setting flags: {}" ~~ unwords opts
+			mdflags <- fmap (join . fmap getFirst) getSessionData
+			dflags <- maybe getSessionDynFlags return mdflags
+			(df', _, _) <- parseDynamicFlags dflags (map noLoc opts)
+			void $ setSessionDynFlags df'
+		pdbsOpts = packageDbStackOpts pdbs
 
 -- | Get ghc session
-ghcSession :: [String] -> GhcM ()
+ghcSession :: PackageDbStack -> [String] -> GhcM ()
 ghcSession = workerSession SessionGhc
 
 -- | Get ghci session
 ghciSession :: GhcM ()
-ghciSession = workerSession SessionGhci []
+ghciSession = workerSession SessionGhci userDb []
 
 -- | Get haddock session with flags
-haddockSession :: [String] -> GhcM ()
+haddockSession :: PackageDbStack -> [String] -> GhcM ()
 haddockSession = workerSession SessionHaddock
 
 -- | Get haddock session with flags
-tmpSession :: [String] -> GhcM ()
+tmpSession :: PackageDbStack -> [String] -> GhcM ()
 tmpSession = workerSession SessionTmp
 
 -- | Run ghc
diff --git a/src/HsDev/Tools/HDocs.hs b/src/HsDev/Tools/HDocs.hs
--- a/src/HsDev/Tools/HDocs.hs
+++ b/src/HsDev/Tools/HDocs.hs
@@ -50,12 +50,12 @@
 import System.Directory.Paths
 
 -- | Get docs for modules
-hdocsy :: [ModuleLocation] -> [String] -> GhcM [Map String String]
+hdocsy :: PackageDbStack -> [ModuleLocation] -> [String] -> GhcM [Map String String]
 #ifndef NODOCS
-hdocsy mlocs opts = (map $ force . HDocs.formatDocs) <$> docs' mlocs where
+hdocsy pdbs mlocs opts = (map $ force . HDocs.formatDocs) <$> docs' mlocs where
 	docs' :: [ModuleLocation] -> GhcM [HDocs.ModuleDocMap]
 	docs' ms = do
-		haddockSession opts
+		haddockSession pdbs opts
 		liftGhc $ hsdevLiftWith (ToolError "hdocs") $
 			liftM (map snd) $ HDocs.readSourcesGhc opts $ map (view (moduleFile . path)) ms
 #else
@@ -63,12 +63,12 @@
 #endif
 
 -- | Get docs for module
-hdocs :: ModuleLocation -> [String] -> GhcM (Map String String)
+hdocs :: PackageDbStack -> ModuleLocation -> [String] -> GhcM (Map String String)
 #ifndef NODOCS
-hdocs mloc opts = (force . HDocs.formatDocs) <$> docs' mloc where
+hdocs pdbs mloc opts = (force . HDocs.formatDocs) <$> docs' mloc where
 	docs' :: ModuleLocation -> GhcM HDocs.ModuleDocMap
 	docs' mloc' = do
-		haddockSession opts
+		haddockSession pdbs opts
 		liftGhc $ case mloc' of
 			(FileModule fpath _) -> hsdevLiftWith (ToolError "hdocs") $ liftM snd $ HDocs.readSourceGhc opts (view path fpath)
 			(InstalledModule _ _ mname) -> do
@@ -101,7 +101,7 @@
 hdocsCabal :: PackageDbStack -> [String] -> GhcM [(ModulePackage, (Map Text (Map Text Text)))]
 #ifndef NODOCS
 hdocsCabal pdbs opts = do
-	haddockSession (packageDbStackOpts pdbs ++ opts)
+	haddockSession pdbs opts
 	pkgs <- packageConfigs
 	forM pkgs $ \pkg -> do
 		pkgDocs' <- hdocsPackage pkg
diff --git a/src/HsDev/Tools/Tabs.hs b/src/HsDev/Tools/Tabs.hs
new file mode 100644
--- /dev/null
+++ b/src/HsDev/Tools/Tabs.hs
@@ -0,0 +1,30 @@
+module HsDev.Tools.Tabs (
+	recalcNotesTabs
+	) where
+
+import Control.Lens
+import Data.Map (Map)
+import qualified Data.Map as M
+import Data.Maybe (fromMaybe)
+import Data.Text (Text)
+
+import System.Directory.Paths
+import HsDev.Symbols.Location
+import HsDev.Tools.Types
+import HsDev.Util
+
+-- | Some tools counts tab as 8 symbols and return such file positions; convert them (consider tab = one symbol)
+recalcNotesTabs :: Map Path Text -> [Note a] -> IO [Note a]
+recalcNotesTabs srcs notes = do
+	ctsMap <- fmap M.fromList $ mapM loadFileContents files
+	let
+		recalc' n = fromMaybe n $ do
+			fname <- preview (noteSource . moduleFile) n
+			cts' <- M.lookup fname ctsMap
+			return $ recalcTabs cts' 8 n
+	return $ map recalc' notes
+	where
+		files = ordNub $ notes ^.. each . noteSource . moduleFile
+		loadFileContents f = do
+			cts <- maybe (readFileUtf8 $ view path f) return $ M.lookup f srcs
+			return (f, cts)
diff --git a/tests/Test.hs b/tests/Test.hs
--- a/tests/Test.hs
+++ b/tests/Test.hs
@@ -34,10 +34,11 @@
 exports v = mkSet (v ^.. traverseArray . key "exports" . traverseArray . key "id" . key "name" . _Just)
 
 rgn :: Maybe Value -> Maybe Region
-rgn v = Region <$> (pos (v ^. key "from")) <*> (pos (v ^. key "to")) where
-	pos :: Maybe Value -> Maybe Position
-	pos v' = Position <$> (v' ^. key "line") <*> (v' ^. key "column")
+rgn v = Region <$> (pos (v ^. key "from")) <*> (pos (v ^. key "to"))
 
+pos :: Maybe Value -> Maybe Position
+pos v = Position <$> (v ^. key "line") <*> (v ^. key "column")
+
 mkSet :: [String] -> S.Set String
 mkSet = S.fromList
 
@@ -47,7 +48,7 @@
 		dir <- runIO getCurrentDirectory
 		s <- runIO $ startServer_ (def { serverSilent = True })
 		it "should load data" $ do
-			inserts <- liftM lines $ readFile (dir </> "tests/data/base.sql")
+			inserts <- fmap lines $ readFile (dir </> "tests/data/base.sql")
 			inServer s $ mapM_ (execute_ . fromString) inserts
 		it "should scan project" $ do
 			void $ send s ["scan", "--project", dir </> "tests/test-package"]
@@ -96,5 +97,29 @@
 		it "should use modified source in `check` command" $ do
 			checks <- send s ["check", "--file", dir </> "tests/test-package/ModuleTwo.hs"]
 			(checks ^.. traverseArray . key "note" . key "message" . _Just) `shouldSatisfy` (any ("Defined but not used" `isPrefixOf`))
+		it "should get usages of symbol" $ do
+			-- Note, that source was modified
+			us <- send s ["usages", "2", "2", "--file", dir </> "tests/test-package/ModuleTwo.hs"]
+			let
+				locs :: [(String, Position)]
+				locs = do
+					n <- us ^.. traverseArray
+					nm <- maybeToList $ n ^. key "in" . key "name"
+					p <- maybeToList $ pos (n ^. key "at")
+					return (nm, p)
+			S.fromList locs `shouldBe` S.fromList [
+				("ModuleOne", Position 4 2),
+				("ModuleTwo", Position 2 2),
+				("ModuleTwo", Position 8 19),
+				("ModuleTwo", Position 25 21),
+				("ModuleTwo", Position 25 35)]
+		it "should get usages of local symbols" $ do
+			us <- send s ["usages", "14", "15", "--file", dir </> "tests/test-package/ModuleTwo.hs"]
+			let
+				locs :: [Position]
+				locs = do
+					n <- us ^.. traverseArray
+					maybeToList $ pos (n ^. key "at")
+			S.fromList locs `shouldBe` S.fromList [Position 14 7, Position 14 11, Position 14 15]
 		_ <- runIO $ send s ["exit"]
 		return ()
