diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,6 +1,12 @@
 Nico Nico Douga (ニコニコ動画) Comment Translator
 =================================================
 
+[![Build Status][0]][1]
+
+[0]: https://travis-ci.org/dahlia/nicovideo-translator.svg
+[1]: https://travis-ci.org/dahlia/nicovideo-translator
+
+
 Installation
 ------------
 
@@ -14,12 +20,12 @@
 
 To make the translator to intercept comments from Nico Nico comment server,
 you have to alias Nico Nico comment server domain (`msg.nicovideo.jp`) to
-your localhost (`127.0.0.1`).  Open your [hosts file][1] using text editor
+your localhost (`127.0.0.1`).  Open your [hosts file][2] using text editor
 (you probably need administrator permission), and then add the following line:
 
     127.0.0.1    msg.nicovideo.jp
 
-[1]: http://en.wikipedia.org/wiki/Hosts_%28file%29
+[2]: http://en.wikipedia.org/wiki/Hosts_%28file%29
 
 
 Proxy server
@@ -30,22 +36,29 @@
 (you probably need administrator permission to listen 80 port):
 
     $ nicovideo-translator
+    Running on http://0.0.0.0:80/ (Press ^C to quit)
+    Upstream: msg.nicovideo.jp (202.248.110.173)
 
 You can terminate the server by pressing Ctrl-C.
 
+It can optionally take the target language which is a two-letter
+e.g. `en`, `ko` through `-l`/`--language` option:
 
+    $ nicovideo-translator --language ko
+
+
 Open source
 -----------
 
-It's written by [Hong Minhee][2], and distributed under [AGPLv3[].
-You can find the source code from the [Git repository][3]:
+It's written by [Hong Minhee][3], and distributed under [AGPLv3][].
+You can find the source code from the [Git repository][4]:
 
     $ git clone git://github.com/dahlia/nicovideo-translator
 
-Please report bugs to the [issue tracker][4] if you find.
+Please report bugs to the [issue tracker][5] if you find.
 Pull requests welcome!
 
-[2]: http://hongminhee.org/
-[3]: https://github.com/dahlia/nicovideo-translator
-[4]: https://github.com/dahlia/nicovideo-translator/issues
+[3]: http://hongminhee.org/
+[4]: https://github.com/dahlia/nicovideo-translator
+[5]: https://github.com/dahlia/nicovideo-translator/issues
 [AGPLv3]: http://www.gnu.org/licenses/agpl-3.0.html
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,3 +1,3 @@
-import Distribution.Simple
+import Distribution.Simple (defaultMain)
 
 main = defaultMain
diff --git a/lib/NicovideoTranslator/Main.hs b/lib/NicovideoTranslator/Main.hs
new file mode 100644
--- /dev/null
+++ b/lib/NicovideoTranslator/Main.hs
@@ -0,0 +1,80 @@
+{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}
+module NicovideoTranslator.Main (main) where
+
+import Data.Char (toLower)
+import System.IO (stderr, stdout)
+import System.IO.Error (catchIOError)
+
+import Data.Data (Data)
+import qualified Data.LanguageCodes as L
+import qualified Data.Text as T
+import Data.Text.Encoding (encodeUtf8)
+import Data.Text.Format (Format, format)
+import Data.Text.Format.Params (Params)
+import Data.Text.Format.Types (Only(Only))
+import Data.Text.IO (hPutStrLn)
+import qualified Data.Text.Lazy as LT
+import Data.Typeable (Typeable)
+import Network.DNS.Resolver (defaultResolvConf, makeResolvSeed, withResolver)
+import Network.DNS.Lookup (lookupA)
+import Network.Wai.Handler.Warp (Port, run)
+import System.Console.CmdArgs (cmdArgs, help, typ, (&=))
+import System.Locale.SetLocale (Category(LC_CTYPE), setLocale)
+
+import NicovideoTranslator.Proxy (ProxyConfiguration(ProxyConfiguration), app)
+
+data Translator = Translator { port :: Port
+                             , language :: String
+                             } deriving (Show, Data, Typeable)
+
+formatIoError :: Params ps => Format -> ps -> IO a
+formatIoError fmt ps = ioError $ userError $ LT.unpack $ format fmt ps 
+
+readLanguageCode :: [Char] -> IO L.ISO639_1
+readLanguageCode (x:y:[]) =
+    case L.fromChars (toLower x) (toLower y) of
+        Just lang -> return lang
+        _ -> formatIoError "{} is wrong language code" (Only (x:y:[]))
+readLanguageCode lang = formatIoError "{} is wrong language code" (Only lang)
+
+currentLanguage :: IO L.ISO639_1
+currentLanguage = do
+    currentLocale <- setLocale LC_CTYPE Nothing
+    case currentLocale of
+        Just s -> readLanguageCode s
+        Nothing -> formatIoError "locale is not set" ()
+
+defaultUpstreamHost :: T.Text
+defaultUpstreamHost = "msg.nicovideo.jp"
+
+translateCmdArgs :: String -> Translator
+translateCmdArgs lang =
+    Translator { language = lang &= typ "LANG"
+                                 &= help "Target language to translate to [en]"
+               , port = 80 &= typ "PORT"
+                           &= help "Port number to listen [80]"
+               }
+
+main :: IO ()
+main = do
+    currentLang <- catchIOError currentLanguage (\_ -> return L.EN)
+    opts <- cmdArgs $ translateCmdArgs $ L.language currentLang
+    lang <- readLanguageCode $ language opts
+    let portNum = port opts
+    hPutStrLn stdout $ LT.toStrict $
+        format "Running on http://0.0.0.0:{}/ (Press ^C to quit)" (Only portNum)
+    rs <- makeResolvSeed defaultResolvConf
+    resolution <- withResolver rs $
+        \resolver -> lookupA resolver (encodeUtf8 defaultUpstreamHost)
+    case resolution of
+        Right (resolvedHost:_) ->
+            let upstreamHost = T.pack $ show resolvedHost
+            in do
+                hPutStrLn stdout $ T.concat ["Upstream: "
+                                            , defaultUpstreamHost
+                                            , " (", upstreamHost, ")"
+                                            ]
+                run portNum $ app (ProxyConfiguration lang upstreamHost)
+        _ -> hPutStrLn stderr $ T.concat [ "error: failed to resolve "
+                                         , defaultUpstreamHost
+                                         ]
diff --git a/lib/NicovideoTranslator/Proxy.hs b/lib/NicovideoTranslator/Proxy.hs
--- a/lib/NicovideoTranslator/Proxy.hs
+++ b/lib/NicovideoTranslator/Proxy.hs
@@ -87,7 +87,7 @@
 request "POST" = postWith
 request "PUT" = putWith
 request "DELETE" = \options url _ -> deleteWith options url
-request _= \_ _ _ -> ioError $ userError $ "unsupported method"
+request _ = \_ _ _ -> ioError $ userError $ "unsupported method"
 
 translateResponse :: ISO639_1 -> LB.ByteString -> IO LB.ByteString
 translateResponse lang response = case parseLBS def response of
diff --git a/lib/NicovideoTranslator/Translate.hs b/lib/NicovideoTranslator/Translate.hs
--- a/lib/NicovideoTranslator/Translate.hs
+++ b/lib/NicovideoTranslator/Translate.hs
@@ -5,44 +5,12 @@
     , translateMultiple
     ) where
 
-import Control.Lens ((^?))
-import Data.Aeson.Lens (key)
-import Data.Aeson.Types (Value(String))
-import Data.LanguageCodes (ISO639_1, language)
-import Data.Text (Text, cons, intercalate, pack, snoc, splitOn, strip)
-import Network.Wreq (FormParam((:=)), post, responseBody)
-import System.Random (getStdRandom, randomR)
+import qualified Language.Translate.Naver as Naver
+import Data.LanguageCodes (ISO639_1(JA))
+import Data.Text (Text)
 
 translate :: ISO639_1 -> Text -> IO Text
-translate lang text =
-    let response =
-            post
-            "http://translate.naver.com/translate.dic"
-            [ "query" := text
-            , "srcLang" := ("ja" :: Text)
-            , "tarLang" := (pack $ language lang)
-            , "highlight" := ("0" :: Text)
-            , "hurigana" := ("0" :: Text)]
-        getResultData resp = resp ^? responseBody . key "resultData"
-        resultData = response >>= return . getResultData
-    in
-        resultData >>= \dat -> case dat of
-            Just (String translated) -> return translated
-            _ -> ioError $ userError "translate.naver.com sent invalid response"
-
-arbitraryNumericLength :: Int
-arbitraryNumericLength = 20
-
-arbitraryNumeric :: IO Text
-arbitraryNumeric =
-    let
-        randomDigit i = getStdRandom (randomR (if i > 1 then '0' else '1', '9'))
-        string = sequence $ map randomDigit [1..arbitraryNumericLength]
-    in
-        string >>= return . pack
+translate = Naver.translate JA
 
 translateMultiple :: ISO639_1 -> [Text] -> IO [Text]
-translateMultiple lang texts = do
-    spliter <- arbitraryNumeric
-    result <- translate lang $ intercalate (snoc (cons ' ' spliter) ' ') texts
-    return $ map strip $ splitOn spliter result
+translateMultiple = Naver.translateMultiple JA
diff --git a/nicovideo-translator.cabal b/nicovideo-translator.cabal
--- a/nicovideo-translator.cabal
+++ b/nicovideo-translator.cabal
@@ -1,5 +1,5 @@
 name:                nicovideo-translator
-version:             0.1.0.0
+version:             0.1.0.1
 synopsis:            Nico Nico Douga (ニコニコ動画) Comment Translator
 homepage:            https://github.com/dahlia/nicovideo-translator
 bug-reports:         https://github.com/dahlia/nicovideo-translator/issues
@@ -15,21 +15,25 @@
 
 library
   hs-source-dirs:      lib
-  exposed-modules:     NicovideoTranslator.Proxy,
+  exposed-modules:     NicovideoTranslator.Main,
+                       NicovideoTranslator.Proxy,
                        NicovideoTranslator.Translate
-  build-depends:       aeson            >=0.7.0.6  && <0.8.0.0,
-                       base             >=4.7      && <4.8,
+  build-depends:       base             >=4.5.0.0  && <4.8.0.0,
                        bytestring       >=0.10.4.0 && <0.11.0.0,
                        case-insensitive >=1.2.0.0  && <1.3.0.0,
+                       cmdargs          >=0.10.12  && <0.11.0,
                        containers,
+                       dns              >=1.4.4    && <1.5.0,
                        http-client      >=0.4.9    && <0.5.0,
                        http-types       >=0.8.6    && <0.9.0,
                        iso639,
                        lens             >=4.8      && <4.9,
-                       lens-aeson       >=1.0.0.3  && <1.1.0.0,
-                       random           >=1.0.1.1  && <1.1.0.0,
+                       naver-translate  >=0.1.0.0  && <0.2.0.0,
+                       setlocale        >=1.0.0.2  && <1.1.0.0,
                        text             >=1.1.0.0  && <1.2.0.0,
+                       text-format      >=0.3.1.1  && <0.4.0.0,
                        wai              >=3.0.2.3  && <3.1.0.0,
+                       warp             >=3.0.10   && <3.1.0,
                        wreq             >=0.3.0.1  && <0.4.0.0,
                        xml-conduit      >=1.2.3.3  && <1.3.0.0
   default-language:    Haskell2010
@@ -39,12 +43,7 @@
 executable nicovideo-translator
   hs-source-dirs:      src
   main-is:             Main.hs
-  build-depends:       base       >=4.7     && <4.8,
-                       dns        >=1.4.4   && <1.5.0,
-                       iso639,
-                       nicovideo-translator,
-                       setlocale  >=1.0.0.2 &&<1.1.0.0,
-                       text       >=1.1.0.0 && <1.2.0.0,
-                       warp       >=3.0.10  && <3.1.0
+  build-depends:       base             >=4.5.0.0  && <4.8.0.0,
+                       nicovideo-translator
   default-language:    Haskell2010
   ghc-options:         -Wall -fwarn-incomplete-uni-patterns -threaded
diff --git a/nicovideo-translator.sig b/nicovideo-translator.sig
deleted file mode 100644
Binary files a/nicovideo-translator.sig and /dev/null differ
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,49 +1,6 @@
-{-# LANGUAGE OverloadedStrings #-}
 module Main (main) where
 
-import Data.Char (toLower)
-import System.IO (stderr, stdout)
-import System.IO.Error (catchIOError)
-
-import Data.LanguageCodes (ISO639_1(EN), fromChars)
-import qualified Data.Text as T
-import Data.Text.Encoding (encodeUtf8)
-import Data.Text.IO (hPutStrLn)
-import Network.DNS.Resolver (defaultResolvConf, makeResolvSeed, withResolver)
-import Network.DNS.Lookup (lookupA)
-import Network.Wai.Handler.Warp (run)
-import System.Locale.SetLocale (Category(LC_CTYPE), setLocale)
-
-import NicovideoTranslator.Proxy (ProxyConfiguration(ProxyConfiguration), app)
-
-language :: IO ISO639_1
-language = do
-    currentLocale <- setLocale LC_CTYPE Nothing
-    case currentLocale of
-        Just (x:y:ys) -> case fromChars (toLower x) (toLower y) of
-            Just lang -> return lang
-            _ -> ioError $ userError $ (x:y:ys) ++ " is wrong LC_CTYPE value"
-        _ -> ioError $ userError "locale is not set"
-
-defaultUpstreamHost :: T.Text
-defaultUpstreamHost = "msg.nicovideo.jp"
+import qualified NicovideoTranslator.Main as M
 
 main :: IO ()
-main = do
-    putStrLn "Running on http://0.0.0.0:80/ (Press ^C to quit)"
-    lang <- catchIOError language (\_ -> return EN)
-    rs <- makeResolvSeed defaultResolvConf
-    resolution <- withResolver rs $
-        \resolver -> lookupA resolver (encodeUtf8 defaultUpstreamHost)
-    case resolution of
-        Right (resolvedHost:_) ->
-            let upstreamHost = T.pack $ show resolvedHost
-            in do
-                hPutStrLn stdout $ T.concat ["Upstream: "
-                                            , defaultUpstreamHost
-                                            , " (", upstreamHost, ")"
-                                            ]
-                run 80 $ app (ProxyConfiguration lang upstreamHost)
-        _ -> hPutStrLn stderr $ T.concat [ "error: failed to resolve "
-                                         , defaultUpstreamHost
-                                         ]
+main = M.main
