diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2014, Yoshikuni Jujo
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Yoshikuni Jujo nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVEN SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,1 @@
+import Distribution.Simple; main = defaultMain
diff --git a/handle-like.cabal b/handle-like.cabal
new file mode 100644
--- /dev/null
+++ b/handle-like.cabal
@@ -0,0 +1,39 @@
+cabal-version:	>= 1.6
+build-type:	Simple
+
+name:		handle-like
+version:	0.0.0.0
+stability:	Experimental
+author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp>
+maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>
+
+license:	BSD3
+license-file:	LICENSE
+
+category:	Common-Parts
+synopsis:	HandleLike class
+description:
+    A tiny package. It's contain the following class.
+    .
+    > class HandleLike h where
+    >     hlPut :: h -> ByteString -> IO ()
+    >     hlGet :: h -> Int -> IO ByteString
+    >     hlGetByte :: h -> IO Word8
+    >     hlGetLine :: h -> IO ByteString
+    >     hlGetContent :: h -> IO ByteString
+    >     hlClose :: h -> IO ()
+
+source-repository	head
+    type:	git
+    location:	git://github.com/YoshikuniJujo/forest
+
+source-repository	this
+    type:	git
+    location:	git://github.com/YoshikuniJujo/forest
+    tag:	handle-like-0.0.0.0
+
+library
+    hs-source-dirs:	src
+    exposed-modules:	Data.HandleLike
+    build-depends:	base == 4.*, bytestring == 0.10.*
+    ghc-options:	-Wall
diff --git a/src/Data/HandleLike.hs b/src/Data/HandleLike.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/HandleLike.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Data.HandleLike (HandleLike(..), hlPutStrLn) where
+
+import Control.Applicative
+import Data.Word
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import System.IO
+
+class HandleLike h where
+	hlPut :: h -> BS.ByteString -> IO ()
+	hlGet :: h -> Int -> IO BS.ByteString
+	hlGetByte :: h -> IO Word8
+	hlGetLine :: h -> IO BS.ByteString
+	hlGetContent :: h -> IO BS.ByteString
+	hlClose :: h -> IO ()
+
+	hlGetByte h = do [b] <- BS.unpack <$> hlGet h 1; return b
+	hlGetLine h = do
+		b <- hlGetByte h
+		case b of
+			10 -> return ""
+			_ -> BS.cons b <$> hlGetLine h
+	hlGetContent = flip hlGet 1
+
+instance HandleLike Handle where
+	hlPut = BS.hPut
+	hlGet = BS.hGet
+--	hlGetByte h = do [b] <- BS.unpack <$> BS.hGet h 1; return b
+	hlGetLine = (chopCR <$>) . BS.hGetLine
+--	hlGetContent = flip BS.hGet 1
+	hlClose = hClose
+
+hlPutStrLn :: HandleLike h => h -> BS.ByteString -> IO ()
+hlPutStrLn h = hlPut h . (`BS.append` "\n")
+
+chopCR :: BS.ByteString -> BS.ByteString
+chopCR bs
+	| BS.null bs = ""
+	| BSC.last bs == '\r' = BSC.init bs
+	| otherwise = bs
