diff --git a/Data-Rope.cabal b/Data-Rope.cabal
--- a/Data-Rope.cabal
+++ b/Data-Rope.cabal
@@ -1,5 +1,5 @@
 Name:		Data-Rope
-Version: 	0.1
+Version: 	0.2
 Synopsis:	Ropes, an alternative to (Byte)Strings.
 Description: 	Ropes : an alternative to Strings,
 		a time and space-efficient representation of character
diff --git a/Data/Rope.lhs b/Data/Rope.lhs
--- a/Data/Rope.lhs
+++ b/Data/Rope.lhs
@@ -46,10 +46,13 @@
   -- * Indexing 'Rope's
   index,
   elemIndex,
+  elemIndex',
   elemIndices,
   -- * Input and Output
   readFile,
   hGet,
+  hGetLine,
+  hGetContents,
   hPut,
   hPutStrLn,
   hPutStr,
@@ -72,7 +75,7 @@
 import qualified Data.ByteString.Internal as B
 import Data.String
 import Data.Word
-
+import Control.Exception (finally)
 #if __GLASGOW_HASKELL__ >=608
 import GHC.IO (IO(IO),unsafePerformIO,unsafeInterleaveIO)
 import GHC.Base (realWorld#)
@@ -83,11 +86,13 @@
 import System.IO.Unsafe
 #endif
 import Data.Maybe
-import GHC.Conc
+import GHC.Conc (par)
 
 import System.Posix (openFd,closeFd,defaultFileFlags,getFileStatus,
                      fileSize,OpenMode(..))
-import System.IO hiding (hPutStrLn,hPutStr,putStrLn,putStr,readFile)
+import System.IO (hGetBuf,hPutBuf,hSeek,hTell,hFileSize,
+                  hPutChar, stdout, hClose)
+
 import qualified Prelude(length,map,splitAt)
 import Prelude hiding (length,null,head,tail,last,init,map,reverse,
                        foldl,foldr,
@@ -298,7 +303,7 @@
 -}
 -- | O(1) Tests whether a 'Rope' is empty.
 null::Rope->Bool
-null x=length x>0
+null x=length x==0
 
 -- | O(1) Length of a 'Rope'.
 length::Rope->Int
@@ -626,12 +631,13 @@
       index_ (Concat{r,l}) i_
         |i_>=length l = index_ r (i_-length l)
         |otherwise = index_ l i_
+                     {-
       index_ (File{handle,position}) i_=
         unsafePerformIO $ alloca $ \cc->do
           hSeek handle AbsoluteSeek $ fromIntegral $ position+i_
           hGetBuf handle cc 1
           peek cc
-
+-}
 
 -- | O(n) returns the index of the first element equal to the query element. This implementation
 -- uses memchr at leaves, and explores the rope in parallel (with 'GHC.Conc.par').
@@ -664,6 +670,36 @@
         x<-peek ptr
         if x==w then return $ Just i else loop (ptr`plusPtr`1) (i+1) l
 
+-- | O(n) Same as 'elemIndex', but explores the 'Rope' sequentially. Useful for
+-- 'Rope's loaded lazily with 'readFile'.
+
+elemIndex'::Word8->Rope->Maybe Int
+elemIndex' w rope=
+  elemIndex_ 0 rope
+  where
+    elemIndex_ i (String{contents,offset,length_})=
+      inlinePerformIO $ withForeignPtr contents $ \con->do
+        ptr<-memchr (con`plusPtr`offset) w (fromIntegral length_)
+        return $ if ptr==nullPtr then Nothing else Just $ i+offset+(ptr`minusPtr`con)
+        
+    elemIndex_ i (Concat{l,r})=
+      case elemIndex_ i l of
+        Nothing->elemIndex_ (i+length l) r
+        a->a
+       
+    elemIndex_ i (File{handle,position,length_})=
+      unsafePerformIO $ allocaBytes length_ $ \c->do
+        hSeek handle AbsoluteSeek $ fromIntegral position
+        l<-hGetBuf handle c length_
+        x<-loop c 0 l
+        return $ x>>=(return.(+i))
+      
+    loop ptr i l
+      | i>=l = return Nothing
+      | otherwise = do
+        x<-peek ptr
+        if x==w then return $ Just i else loop (ptr`plusPtr`1) (i+1) l
+
 -- | O(n) returns the list of all positions where the queried elements occurs in the 'Rope'.
 -- This implementation uses memchr.
 
@@ -921,8 +957,7 @@
 putStrLn::Rope->IO()
 putStrLn=hPutStrLn stdout
   
-
-
+-- | fromPtr encapsule un pointeur, un offset et une longueur dans un @Rope@..
 fromPtr::ForeignPtr Word8->Int->Int->IO Rope
 fromPtr fp offset s
   | s<=leafSize = withForeignPtr fp $ \p->do
@@ -983,6 +1018,7 @@
   fromPtr fp 0 (fromIntegral s)
 
 
+
 -- | Strict hGet. The whole rope is constructed.
 hGet::Handle->Int->IO Rope
 hGet handle length_=do
@@ -1012,5 +1048,55 @@
           bb<-buildRope handle (position+fromIntegral a) b
           return $ Concat { length_=len,l=aa,r=bb,sizeC=size aa+size bb }
   
+-- | Returns the next line in the input 'Handle'. If you need to iterate 'hGetLine',
+-- it may be more efficient to first @mmap@ the file using 'readFile', or even load
+-- it with then iterate
+-- @'breakByte' 0x0a@ : 'hGetLine' allocates a buffer to read the file
+-- and may waste most of this space if the lines are shorter than the standard buffer
+-- size of this module.
+hGetLine::Handle->IO Rope
+hGetLine h=
+  hGetLine' empty
+  
+  where
+    hGetLine' x=do
+      contents<-mallocForeignPtrBytes leafSize
+      withForeignPtr contents $ \con->do
+        l<-hGetBuf h con leafSize
+        let readBytes=min l leafSize
+        if readBytes<=0 then return x else do
+          ptr<-memchr con 0x0a (fromIntegral readBytes)
+          if ptr==nullPtr then do
+            i0<-mallocForeignPtr
+            withForeignPtr i0 $ \i->poke i readBytes
+            let y=String { contents,i0,offset=0,length_=readBytes }
+            hGetLine' (x`append`y)
+          
+            else do
+          
+            i0<-mallocForeignPtr
+            let lineLen=ptr`minusPtr`con
+                y=String { contents,i0,offset=0,length_=lineLen }
+            withForeignPtr i0 $ \i->poke i lineLen
+            hSeek h RelativeSeek (fromIntegral $ lineLen-readBytes+1)
+            return $ x`append`y
+          
+-- | Reads the contents of a file handle strictly, then closes it.
+
+hGetContents::Handle->IO Rope
+hGetContents h=finally (hGetContents' empty) (hClose h)
+
+  where
+    hGetContents' r=do
+      contents<-mallocForeignPtrBytes leafSize
+      withForeignPtr contents $ \l->do
+        x<-hGetBuf h l leafSize
+        i0<-mallocForeignPtr
+        withForeignPtr i0 $ \i->poke i x
+        let y=String { contents,i0,offset=0,length_=x }
+
+        if x==0 then return r else
+          if x<leafSize then return $ r`append`y else
+            hGetContents' $ r`append`y
 \end{code}
 
diff --git a/Data/Rope/Char8.lhs b/Data/Rope/Char8.lhs
new file mode 100644
--- /dev/null
+++ b/Data/Rope/Char8.lhs
@@ -0,0 +1,11 @@
+\begin{code}
+module Data.Rope.Char8 where
+
+import qualified Data.Rope as R
+import Data.Rope.Internals
+
+singleton::Word8->Rope
+singleton x=(R.singleton).w2c
+
+
+\end{code}
diff --git a/Data/Rope/Internals.hsc b/Data/Rope/Internals.hsc
--- a/Data/Rope/Internals.hsc
+++ b/Data/Rope/Internals.hsc
@@ -7,7 +7,7 @@
 import Foreign.Storable
 import Foreign.C.Types
 import Data.Word
-
+import GHC.Base
 
 foreign import ccall unsafe "sys/mman.h mmap" c_mmap::
   Ptr a->CSize->CInt->CInt->CInt->CInt->IO (Ptr Word8)
@@ -32,3 +32,10 @@
 
 c_MAP_FILE::CInt
 c_MAP_FILE= #const MAP_FILE
+
+
+w2c::Word8->Char
+w2c=unsafeChr.fromIntegral
+
+c2w::Char->Word8
+c2w=fromIntegral.ord
