diff --git a/lgtk.cabal b/lgtk.cabal
--- a/lgtk.cabal
+++ b/lgtk.cabal
@@ -1,15 +1,16 @@
 name:               lgtk
-version:            0.2
+version:            0.3
 category:           GUI
 synopsis:           lens-based GUI with Gtk backend
 description:
-    Try the demo executable lgtkdemo and read the source.
+    The main interface of LGtk is "GUI.MLens.Gtk".
     .
-    See also <http://people.inf.elte.hu/divip/LGtk.html>
-stability:          alpha
+    See also <http://people.inf.elte.hu/divip/LGtk/index.html>
+stability:          experimental
 license:            BSD3
 license-file:       LICENSE
 author:             Péter Diviánszky
+homepage:           http://people.inf.elte.hu/divip/LGtk/index.html
 maintainer:         divipp@gmail.com
 cabal-version:      >= 1.8
 build-type:         Simple
@@ -33,19 +34,22 @@
                     Data.MLens.Ref
 
                     Control.MLens.NewRef
+                    Control.MLens.NewRef.Unsafe
                     Control.MLens.ExtRef
                     Control.MLens.ExtRef.Test
                     Control.MLens.ExtRef.Pure
                     Control.MLens.ExtRef.Pure.Test
+                    Control.MLens
 
-                    GUI.MLens.Gtk.Interface
-                    GUI.MLens.Gtk.IO
                     GUI.MLens.Gtk
                     GUI.MLens.Gtk.ADTEditor
 
                     GUI.MLens.Gtk.Demos.Tri
                     GUI.MLens.Gtk.Demos.IntListEditor
                     GUI.MLens.Gtk.Demos.TEditor
+  other-modules:
+                    GUI.MLens.Gtk.IO
+                    GUI.MLens.Gtk.Interface
   ghc-options: 
                     -Wall 
                     -fno-warn-incomplete-patterns 
diff --git a/main/Main.hs b/main/Main.hs
--- a/main/Main.hs
+++ b/main/Main.hs
@@ -1,8 +1,7 @@
-{-# LANGUAGE RankNTypes #-}
 import Control.Monad
 import Control.Monad.Trans
-import Prelude hiding ((.), id)
 
+import Data.MLens.Ref (fileRef)
 import GUI.MLens.Gtk
 
 import GUI.MLens.Gtk.Demos.Tri
@@ -11,7 +10,7 @@
 
 
 {- |
-We use @unsafeRunI@ only because we read from an write to a file.
+We use @unsafeRunI@ only because we read from and write to a file.
 It is considered unsafe usage, because the system do not guarantee that only this
 program acesses the files at runtime.
 -}
diff --git a/src/Control/MLens.hs b/src/Control/MLens.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/MLens.hs
@@ -0,0 +1,56 @@
+-- {-# LANGUAGE ExistentialQuantification #-}
+-- {-# LANGUAGE RankNTypes #-}
+-- | The main monadic lens interface, ideally users should import only this module.
+module Control.MLens
+    ( -- * Data types
+      MLens
+    , Lens
+    , Ref
+
+    -- * Lens operations
+    , getL, setL, modL
+
+    -- * Lens transformations
+    , fromLens, toLens
+    , mapMLens
+    , (.)
+    , (***)
+    , joinML, joinLens
+    , memoMLens
+
+    -- * Pure lenses
+    , id
+    , unitLens
+    , fstLens, sndLens
+    , maybeLens
+    , listLens
+    , ithLens
+
+    -- * Impure lenses
+    , lens
+    , forkLens
+    , justLens
+    , showLens
+
+    -- * Reference operations
+    , readRef, writeRef, modRef
+    , NewRef (..)
+    , ExtRef (..)
+    , Ext, runExt, runExt_
+    , undoTr
+
+    -- * Auxiliary definitions
+    , Morph
+    , memoRead
+    , memoWrite
+    ) where
+
+import Control.Category
+import Prelude hiding ((.), id)
+
+import Data.MLens
+import Data.MLens.Ref
+import Control.MLens.ExtRef
+import Control.MLens.ExtRef.Pure
+
+
diff --git a/src/Control/MLens/ExtRef/Pure.hs b/src/Control/MLens/ExtRef/Pure.hs
--- a/src/Control/MLens/ExtRef/Pure.hs
+++ b/src/Control/MLens/ExtRef/Pure.hs
@@ -70,7 +70,7 @@
 instance MonadTrans (Ext i) where
     lift = Ext . lift
 
-extRef_ :: Monad m => MLens (Ext i m) a x -> MLens (Ext i m) a x -> a -> Ext i m (Ref (Ext i m) a)
+extRef_ :: Monad m => Ref (Ext i m) x -> MLens (Ext i m) a x -> a -> Ext i m (Ref (Ext i m) a)
 extRef_ r1 r2 a0 = Ext $ do
     a1 <- g a0
     (t,z) <- state $ extend_ (runStateT . f) (runStateT . g) a1
@@ -79,14 +79,14 @@
             , \a -> Ext $ (StateT $ liftM ((,) ()) . z a) >> return c
             )
    where
-    f b = unExt $ getL r2 b >>= flip (setL r1) b
-    g b = unExt $ getL r1 b >>= flip (setL r2) b
+    f a = unExt $ getL r2 a >>= \x -> writeRef r1 x >> return a
+    g b = unExt $ readRef r1 >>= flip (setL r2) b
 
 instance (Monad m) => NewRef (Ext i m) where
     newRef = extRef_ unitLens unitLens
 
 instance (Monad m) => ExtRef (Ext i m) where
-    extRef = extRef_ . (. unitLens)
+    extRef = extRef_
 
 -- | Basic running of the @(Ext i m)@ monad.
 runExt :: Monad m => (forall i . Ext i m a) -> m a
diff --git a/src/Control/MLens/NewRef.hs b/src/Control/MLens/NewRef.hs
--- a/src/Control/MLens/NewRef.hs
+++ b/src/Control/MLens/NewRef.hs
@@ -10,10 +10,8 @@
     , memoRead, memoWrite
     ) where
 
-import Data.IORef
 import Control.Monad
 import Control.Monad.Writer
-import Prelude -- hiding ((.), id)
 
 import Data.MLens
 import Data.MLens.Ref
@@ -25,14 +23,6 @@
 -}
 class (Monad m) => NewRef m where
     newRef :: a -> m (Ref m a)
-
--- | Note that this instance does not fulfil the @NewRef@ laws in a multi-threaded environment.
-instance NewRef IO where
-    newRef x = do
-        r <- newIORef x
-        return $ MLens $ \() -> do
-            x <- readIORef r
-            return (x, writeIORef r)
 
 instance (NewRef m, Monoid w) => NewRef (WriterT w m) where
     newRef = liftM (mapMLens lift) . lift . newRef
diff --git a/src/Control/MLens/NewRef/Unsafe.hs b/src/Control/MLens/NewRef/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/MLens/NewRef/Unsafe.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE RankNTypes #-}
+-- | This module export only the @NewRef@ instance for @IO@ which does not fulfil the @NewRef@ laws in a multi-threaded environment.
+module Control.MLens.NewRef.Unsafe
+    () where
+
+import Data.IORef
+
+import Data.MLens
+import Control.MLens.NewRef
+
+-- | Note that this instance does not fulfil the @NewRef@ laws in a multi-threaded environment.
+instance NewRef IO where
+    newRef x = do
+        r <- newIORef x
+        return $ MLens $ \unit -> do
+            x <- readIORef r
+            return (x, \y -> writeIORef r y >> return unit)
+
+
diff --git a/src/Data/MLens.hs b/src/Data/MLens.hs
--- a/src/Data/MLens.hs
+++ b/src/Data/MLens.hs
@@ -97,6 +97,7 @@
 toLens :: (forall m . Monad m => MLens m a b) -> Lens a b
 toLens k = k
 
+-- | Impure (but effect-free) lens constuctor
 lens :: Monad m => (a -> b) -> (b -> a -> a) -> MLens m a b
 lens get set = MLens $ \a -> return (get a, return . flip set a)
 
diff --git a/src/Data/MLens/Ref.hs b/src/Data/MLens/Ref.hs
--- a/src/Data/MLens/Ref.hs
+++ b/src/Data/MLens/Ref.hs
@@ -1,8 +1,10 @@
 {-# LANGUAGE RankNTypes #-}
 module Data.MLens.Ref
-    ( -- * Data type for reference lenses
-      Ref
+    ( Unit
 
+    -- * Data type for reference lenses
+    , Ref
+
     -- * Reference operations
     , readRef, writeRef, modRef
 
@@ -21,6 +23,13 @@
 
 import Data.MLens
 
+{- | 
+The abstract data type @Unit@ is isomorphic to @()@,
+but by making it abstract we can prevent using references
+on the left hand side of lens composition.
+-}
+data Unit = Unit deriving (Eq, Show)
+
 {- |
 Note that references lenses can be composed with lenses.
 For example, if
@@ -33,7 +42,7 @@
 
 Reference laws for pure references:
 
- *  @(readRef r)@ has no side effect
+ *  @(readRef r >> return ())@ === @(return ())@
 
  *  @(readRef r >>= writeRef r)@ === @(return ())@
 
@@ -41,21 +50,18 @@
 
  *  @(writeRef r a >> writeRef r a')@ === @(writeRef r a')@
 
- *  Reference laws need not be preserved by composition, but they should be preserved if a
-    pure lens is composed from the left.
-
-These first four laws are equivalent to the get-no-effect, set-get, get-set and set-set laws for monadic lenses.
+These laws are equivalent to the get-no-effect, set-get, get-set and set-set laws for monadic lenses.
 -}
-type Ref m a = MLens m () a
+type Ref m a = MLens m Unit a
 
-readRef :: Monad m => MLens m () a -> m a
-readRef k = getL k ()
+readRef :: Monad m => MLens m Unit a -> m a
+readRef k = getL k Unit
 
 writeRef :: Monad m => Ref m a -> a -> m ()
-writeRef r a = setL r a ()
+writeRef r a = setL r a Unit >> return ()
 
 modRef :: Monad m => Ref m a -> (a -> a) -> m ()
-k `modRef` f = modL k f ()
+k `modRef` f = modL k f Unit >> return ()
 
 -- | Using @fileRef@ is safe if the file is not used concurrently.
 fileRef :: FilePath -> IO (Ref IO String)
@@ -63,13 +69,16 @@
 
 -- | Note that if you write @Nothing@, the file is deleted.
 fileRef_ :: FilePath -> IO (Ref IO (Maybe String))
-fileRef_ f = return $ MLens $ \() -> do
+fileRef_ f = return $ MLens $ \Unit -> do
     b <- doesFileExist f
     if b then do
             xs <- readFile f
             length xs `seq` return (Just xs, wr)
          else return (Nothing, wr)
- where wr = maybe (doesFileExist f >>= \b -> when b (removeFile f)) (writeFile f)
+ where
+    wr mb = do
+        maybe (doesFileExist f >>= \b -> when b (removeFile f)) (writeFile f) mb
+        return Unit
 
 logMLens :: Monad m => (a -> m ()) -> (a -> m ()) -> MLens m a a
 logMLens getLog setLog = MLens $ \a -> getLog a >> return (a, \b -> setLog b >> return b)
diff --git a/src/GUI/MLens/Gtk.hs b/src/GUI/MLens/Gtk.hs
--- a/src/GUI/MLens/Gtk.hs
+++ b/src/GUI/MLens/Gtk.hs
@@ -2,22 +2,20 @@
 {-# LANGUAGE RankNTypes #-}
 -- | The main LGtk interface, ideally users should import only this module.
 module GUI.MLens.Gtk
-    ( module Control.Category
-    , module Data.MLens
-    , module Data.MLens.Ref
-    , module Control.MLens.ExtRef
-    , module GUI.MLens.Gtk.Interface
-
-    -- * Running (rendering) and interface description
-    , runI
-    , unsafeRunI
+    ( -- * Lenses and references
+      module Control.MLens
 
-    -- * Composed
+    -- * GUI combinators
+    , I (..)
+    , ListLayout (..)
     , vcat, hcat
     , smartButton
 
+    -- * Running GUI descriptions
+    , runI
+    , unsafeRunI
+
     -- * Auxiliary functions
-    , mapI
     , toFree
     ) where
 
@@ -25,11 +23,8 @@
 import Control.Monad.Free
 import Prelude hiding ((.), id)
 
-import Data.MLens
-import Data.MLens.Ref
-import Control.MLens.ExtRef
+import Control.MLens
 import GUI.MLens.Gtk.Interface
-import Control.MLens.ExtRef.Pure
 import qualified GUI.MLens.Gtk.IO as Gtk
 
 vcat :: [I m] -> I m
@@ -40,16 +35,16 @@
 
 smartButton
   :: (Eq a, Monad m, Functor m) =>
-     Free m String -> (a -> m a) -> MLens m () a -> I m
+     Free m String -> (a -> m a) -> Ref m a -> I m
 smartButton s f k =
     Button s $ toFree $ readRef k >>= \x -> f x >>= \y -> 
         if y == x then return Nothing else return $ Just ((readRef k >>= f) >>= writeRef k)
 
--- | Run (render) and interface description
+-- | Run an interface description
 runI :: (forall m . (Functor m, ExtRef m) => I m) -> IO ()
 runI e = runExt_ mapI e >>= Gtk.runI
 
--- | Run (render) and interface description
+-- | Run an interface description
 --
 -- Unsafe only if you do nasty things in the @IO@ monad, like forking threads
 unsafeRunI :: (forall i . I (Ext i IO)) -> IO ()
diff --git a/src/GUI/MLens/Gtk/IO.hs b/src/GUI/MLens/Gtk/IO.hs
--- a/src/GUI/MLens/Gtk/IO.hs
+++ b/src/GUI/MLens/Gtk/IO.hs
@@ -12,8 +12,8 @@
 
 import Graphics.UI.Gtk
 
-import Data.MLens.Ref
-import Control.MLens.NewRef
+import Control.MLens
+import Control.MLens.NewRef.Unsafe ()
 import GUI.MLens.Gtk.Interface
 
 ------------------
