diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,1 @@
+language: haskell
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright 2012 Edward Kmett
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 EVENT SHALL THE AUTHORS 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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/runhaskell
+> module Main (main) where
+
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/lens.cabal b/lens.cabal
new file mode 100644
--- /dev/null
+++ b/lens.cabal
@@ -0,0 +1,33 @@
+name:          lens
+category:      Data, Lenses
+version:       0.1
+license:       BSD3
+cabal-version: >= 1.6
+license-file:  LICENSE
+author:        Edward A. Kmett
+maintainer:    Edward A. Kmett <ekmett@gmail.com>
+stability:     provisional
+homepage:      http://github.com/ekmett/lens/
+bug-reports:   http://github.com/ekmett/lens/issues
+copyright:     Copyright (C) 2012 Edward A. Kmett
+synopsis:      Lenses and Lens Families
+description:   Lenses and Lens Families
+build-type:    Simple
+extra-source-files: .travis.yml
+
+source-repository head
+  type: git
+  location: git://github.com/ekmett/lens.git
+
+library
+  exposed-modules:
+    Control.Lens
+    Control.Lens.Multi
+  ghc-options:    -Wall -fwarn-tabs -O2 -fdicts-cheap
+  hs-source-dirs: src
+  build-depends:
+    base             == 4.*,
+    containers       >= 0.3     && < 0.6,
+    mtl              >= 2.1.1   && < 2.2,
+    template-haskell >= 2.4     && < 2.8,
+    transformers     >= 0.2     && < 0.4
diff --git a/src/Control/Lens.hs b/src/Control/Lens.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Lens.hs
@@ -0,0 +1,384 @@
+{-# LANGUAGE Rank2Types, TemplateHaskell #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Lens
+-- Copyright   :  (C) 2012 Edward Kmett
+--                (C) 2012 Dan Burton
+-- License     :  BSD-style (see the file LICENSE)
+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- A self-contained lens library with lenses that are compatible with other
+-- van Laarhoven lens libraries.
+--
+-- Lenses produced by this library are compatible with other van Laarhoven
+-- lens family libraries, such as lens-family, lens-family-core and
+-- lens-family-th, but the API is simpler.
+--
+-- Note: If you merely want your library to provide lenses you may not have
+-- to actually import _any_ lens library, for a "Lens Bar Foo", just export
+-- a function with the signature:
+--
+-- > foo :: Functor f => (Foo -> f Foo) -> Bar -> f Bar
+--
+-- and then you can compose it with other lenses using (.).
+----------------------------------------------------------------------------
+module Control.Lens
+  (
+  -- * Lenses
+    Lens
+  , LensFamily
+
+  -- * Constructing lenses
+  , makeLenses
+  , makeLensesBy
+  , makeLensesFor
+  , lens
+  , iso
+  , clone
+
+  -- * Reading from lenses
+  , getL, modL, setL
+  , (^.), (^$)
+  , (^%=), (^=), (^+=), (^-=), (^*=), (^/=), (^||=), (^&&=)
+
+  -- * Manipulating state
+  , access
+  , Focus(..)
+  , (%=), (~=), (%%=), (+=), (-=), (*=), (//=), (||=), (&&=)
+
+  -- * Common lenses
+  , fstLens
+  , sndLens
+  , mapLens
+  , intMapLens
+  , setLens
+  , intSetLens
+
+  -- ** Getters
+  , Getter
+  , getting
+
+  -- ** Setters
+  , Setter
+  , SetterFamily
+  , setting
+
+  -- * Implementation details
+  , IndexedStore(..)
+  , Focusing(..)
+  ) where
+
+import           Control.Applicative
+import           Control.Monad (liftM)
+import           Control.Monad.State.Class
+import qualified Control.Monad.Trans.State.Lazy as Lazy
+import qualified Control.Monad.Trans.State.Strict as Strict
+import           Control.Monad.Trans.Reader
+import           Data.Char (toLower)
+import           Data.Functor.Identity
+import           Data.IntMap as IntMap
+import           Data.IntSet as IntSet
+import           Data.Map as Map
+import           Data.Set as Set
+import           Language.Haskell.TH
+
+infixl 8 ^.
+infixr 4 ^%=, ^=, ^+=, ^*=, ^-=, ^/=, ^&&=, ^||=
+infix  4 ~=, %=, %%=, +=, -=, *=, //=, &&=, ||=
+infixr 0 ^$
+
+type Lens a b                 = forall f. Functor f => (b -> f b) -> a -> f a
+type LensFamily a b c d       = forall f. Functor f => (c -> f d) -> a -> f b
+type Getter a b               = forall x y z. (b -> Const z x) -> a -> Const z y
+type Setter a b               = (b -> Identity b) -> a -> Identity a
+type SetterFamily a b c d     = (c -> Identity d) -> a -> Identity b
+
+lens :: Functor f => (a -> c) -> (d -> a -> b) -> (c -> f d) -> a -> f b
+lens ac dab cfd a = (`dab` a) <$> cfd (ac a)
+{-# INLINE lens #-}
+
+iso :: Functor f => (a -> c) -> (d -> b) -> (c -> f d) -> a -> f b
+iso f g h a = g <$> h (f a )
+{-# INLINE iso #-}
+
+getting :: (a -> c) -> (c -> Const r d) -> a -> Const r b
+getting f g a = Const (getConst (g (f a)))
+{-# INLINE getting #-}
+
+setting :: ((c -> d) -> a -> b) -> (c -> Identity d) -> a -> Identity b
+setting f g a = Identity (f (runIdentity . g) a)
+{-# INLINE setting #-}
+
+------------------------------------------------------------------------------
+-- Using Lenses
+------------------------------------------------------------------------------
+
+getL :: ((c -> Const c d) -> a -> Const c b) -> a -> c
+getL l a = getConst (l Const a)
+{-# INLINE getL #-}
+
+modL :: ((c -> Identity d) -> a -> Identity b) -> (c -> d) -> a -> b
+modL l f a = runIdentity (l (Identity . f) a)
+{-# INLINE modL #-}
+
+setL :: ((c -> Identity d) -> a -> Identity b) -> d -> a -> b
+setL l d a = runIdentity (l (\_ -> Identity d) a)
+{-# INLINE setL #-}
+
+(^$) :: ((c -> Const c d) -> a -> Const c b) -> a -> c
+l ^$ a = getConst (l Const a)
+{-# INLINE (^$) #-}
+
+(^.) :: a -> ((c -> Const c d) -> a -> Const c b) -> c
+a ^. l = getConst (l Const a)
+{-# INLINE (^.) #-}
+
+(^%=) :: ((c -> Identity d) -> a -> Identity b) -> (c -> d) -> a -> b
+l ^%= f = runIdentity . l (Identity . f)
+{-# INLINE (^%=) #-}
+
+(^=) :: ((c -> Identity d) -> a -> Identity b) -> d -> a -> b
+l ^= v = runIdentity . l (Identity . const v)
+{-# INLINE (^=) #-}
+
+(^+=) :: Num c => ((c -> Identity c) -> a -> Identity a) -> c -> a -> a
+l ^+= n = modL l (+ n)
+{-# INLINE (^+=) #-}
+
+(^*=) :: Num c => ((c -> Identity c) -> a -> Identity a) -> c -> a -> a
+l ^-= n = modL l (`subtract` n)
+{-# INLINE (^-=) #-}
+
+(^-=) :: Num c => ((c -> Identity c) -> a -> Identity a) -> c -> a -> a
+l ^*= n = modL l (* n)
+{-# INLINE (^*=) #-}
+
+(^/=) :: Fractional c => ((c -> Identity c) -> a -> Identity a) -> c -> a -> a
+l ^/= n = modL l (/ n)
+
+(^||=):: ((Bool -> Identity Bool) -> a -> Identity a) -> Bool -> a -> a
+l ^||= n = modL l (|| n)
+{-# INLINE (^||=) #-}
+
+(^&&=) :: ((Bool -> Identity Bool) -> a -> Identity a) -> Bool -> a -> a
+l ^&&= n = modL l (&& n)
+{-# INLINE (^&&=) #-}
+
+------------------------------------------------------------------------------
+-- Cloning Lenses
+------------------------------------------------------------------------------
+
+data IndexedStore c d a = IndexedStore (d -> a) c
+
+instance Functor (IndexedStore c d) where
+  fmap f (IndexedStore g c) = IndexedStore (f . g) c
+
+clone :: Functor f => ((c -> IndexedStore c d d) -> a -> IndexedStore c d b) -> (c -> f d) -> a -> f b
+clone f cfd a = case f (IndexedStore id) a of
+  IndexedStore db c -> db <$> cfd c
+{-# INLINE clone #-}
+
+------------------------------------------------------------------------------
+-- Common Lenses
+------------------------------------------------------------------------------
+
+fstLens :: LensFamily (a,c) (b,c) a b
+fstLens f (a,c) = (\b -> (b,c)) <$> f a
+{-# INLINE fstLens #-}
+
+sndLens :: LensFamily (c,a) (c,b) a b
+sndLens f (c,a) = (,) c <$> f a
+{-# INLINE sndLens #-}
+
+mapLens :: Ord k => k -> Lens (Map k v) (Maybe v)
+mapLens k f m = go <$> f (Map.lookup k m) where
+  go Nothing   = Map.delete k m
+  go (Just v') = Map.insert k v' m
+{-# INLINE mapLens #-}
+
+intMapLens :: Int -> Lens (IntMap v) (Maybe v)
+intMapLens k f m = go <$> f (IntMap.lookup k m) where
+  go Nothing   = IntMap.delete k m
+  go (Just v') = IntMap.insert k v' m
+{-# INLINE intMapLens #-}
+
+setLens :: Ord k => k -> Lens (Set k) Bool
+setLens k f s = go <$> f (Set.member k s) where
+  go False = Set.delete k s
+  go True  = Set.insert k s
+{-# INLINE setLens #-}
+
+intSetLens :: Int -> Lens IntSet Bool
+intSetLens k f s = go <$> f (IntSet.member k s) where
+  go False = IntSet.delete k s
+  go True  = IntSet.insert k s
+{-# INLINE intSetLens #-}
+
+------------------------------------------------------------------------------
+-- State
+------------------------------------------------------------------------------
+
+access :: MonadState a m => ((c -> Const c d) -> a -> Const c b) -> m c
+access l = gets (^. l)
+{-# INLINE access #-}
+
+newtype Focusing m c a = Focusing { unfocusing :: m (c, a) }
+
+instance Monad m => Functor (Focusing m c) where
+  fmap f (Focusing m) = Focusing (liftM (fmap f) m)
+
+class Focus st where
+  focus :: Monad m => ((b -> Focusing m c b) -> a -> Focusing m c a) -> st b m c -> st a m c
+
+instance Focus Strict.StateT where
+  focus l (Strict.StateT m) = Strict.StateT $ \a -> unfocusing (l (Focusing . m) a)
+
+instance Focus Lazy.StateT where
+  focus l (Lazy.StateT m) = Lazy.StateT $ \a -> unfocusing (l (Focusing . m) a)
+
+instance Focus ReaderT where
+  focus l (ReaderT m) = ReaderT $ \a -> liftM undefined $  unfocusing $ l (\b -> Focusing $ (\c -> (c,b)) `liftM` m b) a
+
+(~=) :: MonadState a m => Setter a b -> b -> m ()
+l ~= b = modify (l ^= b)
+{-# INLINE (~=) #-}
+
+(%=) :: MonadState a m => Setter a b -> (b -> b) -> m ()
+l %= f = modify (l ^%= f)
+{-# INLINE (%=) #-}
+
+(%%=) :: MonadState a m => ((b -> (c,b)) -> a -> (c,a)) -> (b -> (c, b)) -> m c
+l %%= f = state (l f)
+{-# INLINE (%%=) #-}
+
+(+=) :: (MonadState a m, Num b) => Setter a b -> b -> m ()
+l += b = modify $ l ^+= b
+{-# INLINE (+=) #-}
+
+(-=) :: (MonadState a m, Num b) => Setter a b -> b -> m ()
+l -= b = modify $ l ^-= b
+{-# INLINE (-=) #-}
+
+(*=) :: (MonadState a m, Num b) => Setter a b -> b -> m ()
+l *= b = modify $ l ^*= b
+{-# INLINE (*=) #-}
+
+(//=) ::  (MonadState a m, Fractional b) => Setter a b -> b -> m ()
+l //= b = modify $ l ^/= b
+{-# INLINE (//=) #-}
+
+(&&=):: MonadState a m => Setter a Bool -> Bool -> m ()
+l &&= b = modify $ l ^&&= b
+{-# INLINE (&&=) #-}
+
+(||=) :: MonadState a m => Setter a Bool -> Bool -> m ()
+l ||= b = modify $ l ^||= b
+{-# INLINE (||=) #-}
+
+------------------------------------------------------------------------------
+-- Template Haskell
+------------------------------------------------------------------------------
+
+-- | By default, if the field name begins with an underscore,
+-- then the underscore will simply be removed (and the new first character
+-- lowercased if necessary).
+defaultNameTransform :: String -> Maybe String
+defaultNameTransform ('_':c:rest) = Just $ toLower c : rest
+defaultNameTransform _ = Nothing
+
+-- | Information about the larger type the lens will operate on.
+type LensTypeInfo = (Name, [TyVarBndr])
+
+-- | Information about the smaller type the lens will operate on.
+type ConstructorFieldInfo = (Name, Strict, Type)
+
+-- | Derive lenses with the provided name transformation
+-- and filtering function. Produce @Just lensName@ to generate a lens
+-- of the resultant name, or @Nothing@ to not generate a lens
+-- for the input record name.
+--
+-- Example usage:
+--
+-- > makeLensesBy (\n -> Just (n ++ "L")) ''Foo
+makeLensesBy ::
+     (String -> Maybe String) -- ^ the name transformer
+  -> Name -> Q [Dec]
+makeLensesBy nameTransform datatype = do
+  typeInfo          <- extractLensTypeInfo datatype
+  let derive1 = deriveLens nameTransform typeInfo
+  constructorFields <- extractConstructorFields datatype
+  concat <$> mapM derive1 constructorFields
+
+extractLensTypeInfo :: Name -> Q LensTypeInfo
+extractLensTypeInfo datatype = do
+  let datatypeStr = nameBase datatype
+  i <- reify datatype
+  return $ case i of
+    TyConI (DataD    _ n ts _ _) -> (n, ts)
+    TyConI (NewtypeD _ n ts _ _) -> (n, ts)
+    _ -> error $ "Can't derive Lens for: "  ++ datatypeStr ++ ", type name required."
+
+extractConstructorFields :: Name -> Q [ConstructorFieldInfo]
+extractConstructorFields datatype = do
+  let datatypeStr = nameBase datatype
+  i <- reify datatype
+  return $ case i of
+    TyConI (DataD    _ _ _ [RecC _ fs] _) -> fs
+    TyConI (NewtypeD _ _ _ (RecC _ fs) _) -> fs
+    TyConI (DataD    _ _ _ [_]         _) -> error $ "Can't derive Lens without record selectors: " ++ datatypeStr
+    TyConI NewtypeD{} -> error $ "Can't derive Lens without record selectors: " ++ datatypeStr
+    TyConI TySynD{}   -> error $ "Can't derive Lens for type synonym: " ++ datatypeStr
+    TyConI DataD{}    -> error $ "Can't derive Lens for tagged union: " ++ datatypeStr
+    _                 -> error $ "Can't derive Lens for: "  ++ datatypeStr ++ ", type name required."
+
+-- Derive a lens for the given record selector
+-- using the given name transformation function.
+deriveLens :: (String -> Maybe String)
+           -> LensTypeInfo
+           -> ConstructorFieldInfo
+           -> Q [Dec]
+deriveLens nameTransform ty field = case nameTransform (nameBase fieldName) of
+  Nothing          -> return []
+  Just lensNameStr -> do
+    body <- deriveLensBody (mkName lensNameStr) fieldName
+    return [body]
+  where 
+    (fieldName, _fieldStrict, _fieldType) = field
+    (_tyName, _tyVars) = ty  -- just to clarify what's here
+
+-- Given a record field name,
+-- produces a single function declaration:
+-- lensName f a = (\x -> a { field = x }) `fmap` f (field a)
+deriveLensBody :: Name -> Name -> Q Dec
+deriveLensBody lensName fieldName = funD lensName [defLine]
+  where
+    a = mkName "a"
+    f = mkName "f"
+    defLine = clause pats (normalB body) []
+    pats = [varP f, varP a]
+    body = [| (\x -> $(record a fieldName [|x|]))
+              `fmap` $(appE (varE f) (appE (varE fieldName) (varE a)))
+            |]
+    record rec fld val = val >>= \v -> recUpdE (varE rec) [return (fld, v)]
+
+-- | Derive lenses for the record selectors in
+-- a single-constructor data declaration,
+-- or for the record selector in a newtype declaration.
+-- Lenses will only be generated for record fields which
+-- are prefixed with an underscore.
+--
+-- Example usage:
+--
+-- > makeLenses ''Foo
+makeLenses :: Name -> Q [Dec]
+makeLenses = makeLensesBy defaultNameTransform
+
+-- | Derive lenses, specifying explicit pairings of @(fieldName, lensName)@.
+--
+-- Example usage:
+--
+-- > makeLensesFor [("_foo", "fooLens"), ("bar", "lbar")] ''Foo
+makeLensesFor :: [(String, String)] -> Name -> Q [Dec]
+makeLensesFor fields = makeLensesBy (`Prelude.lookup` fields)
diff --git a/src/Control/Lens/Multi.hs b/src/Control/Lens/Multi.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Lens/Multi.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE Rank2Types #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Lens.Multi
+-- Copyright   :  (C) 2012 Edward Kmett
+-- License     :  BSD-style (see the file LICENSE)
+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Note: 'traverse' is a 'MultiLensFamily'
+----------------------------------------------------------------------------
+module Control.Lens.Multi
+  (
+  -- * Lenses
+    MultiLens
+  , MultiLensFamily
+
+  -- * Common lenses
+  , constML
+  , mapML
+  , intMapML
+  , headML
+  , tailML
+  , leftML
+  , elementML
+  ) where
+
+import Control.Applicative
+import Data.IntMap as IntMap
+import Data.Map as Map
+import Data.Traversable
+
+type MultiLens a b          = forall f. Applicative f => (b -> f b) -> a -> f a
+type MultiLensFamily a b c d = forall f. Applicative f => (c -> f d) -> a -> f b
+
+constML :: Applicative f => (a -> f a) -> b -> f b
+constML = const pure
+
+headML :: Applicative f => (a -> f a) -> [a] -> f [a]
+headML _ [] = pure []
+headML f (a:as) = (:as) <$> f a
+{-# INLINE headML #-}
+
+tailML :: Applicative f => ([a] -> f [a]) -> [a] -> f [a]
+tailML _ [] = pure []
+tailML f (a:as) = (a:) <$> f as
+{-# INLINE tailML #-}
+
+leftML :: Applicative f => (a -> f b) -> Either a c -> f (Either b c)
+leftML f (Left a)  = Left <$> f a
+leftML _ (Right c) = pure $ Right c
+{-# INLINE leftML #-}
+
+mapML :: (Applicative f, Ord k) => k -> (v -> f v) -> Map k v -> f (Map k v)
+mapML k f m = case Map.lookup k m of
+  Nothing -> pure m
+  Just v -> (\v' -> Map.insert k v' m) <$> f v
+{-# INLINE mapML #-}
+
+intMapML :: Applicative f => Int -> (v -> f v) -> IntMap v -> f (IntMap v)
+intMapML k f m = case IntMap.lookup k m of
+  Nothing -> pure m
+  Just v -> (\v' -> IntMap.insert k v' m) <$> f v
+{-# INLINE intMapML #-}
+
+newtype SA f a = SA { runSA :: Int -> (f a, Int) }
+
+instance Functor f => Functor (SA f) where
+  fmap f (SA m) = SA $ \i -> case m i of
+    (fa, j) -> (fmap f fa, j)
+
+instance Applicative f => Applicative (SA f) where
+  pure a = SA (\i -> (pure a, i))
+  SA mf <*> SA ma = SA $ \i -> case mf i of
+    (ff, j) -> case ma j of
+       (fa, k) -> (ff <*> fa, k)
+
+elementML :: (Applicative f, Traversable t) => Int -> (a -> f a) -> t a -> f (t a)
+elementML j f ta = fst (runSA (traverse go ta) 0) where
+  go a = SA $ \i -> (if i == j then f a else pure a, i + 1)
