diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2009, Sven Panne
+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 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 EVENT SHALL THE COPYRIGHT OWNER 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,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/StateVar.cabal b/StateVar.cabal
new file mode 100644
--- /dev/null
+++ b/StateVar.cabal
@@ -0,0 +1,17 @@
+name: StateVar
+version: 1.0.0.0
+license: BSD3
+license-file: LICENSE
+maintainer: Sven Panne <sven.panne@aedion.de>
+bug-reports: mailto:hopengl@haskell.org
+homepage: http://www.haskell.org/HOpenGL/
+category: Data
+synopsis: State variables
+description:
+   This package contains state variables, which are references in the IO monad,
+   like IORefs or parts of the OpenGL state.
+build-type: Simple
+exposed-modules: Data.StateVar
+hs-Source-Dirs: src
+ghc-options: -Wall
+build-depends: base >= 3 && < 5
diff --git a/src/Data/StateVar.hs b/src/Data/StateVar.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/StateVar.hs
@@ -0,0 +1,145 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      :  Data.StateVar
+-- Copyright   :  (c) Sven Panne 2009
+-- License     :  BSD-style (see the file LICENSE)
+-- 
+-- Maintainer  :  sven.panne@aedion.de
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- State variables are references in the IO monad, like 'IORef's or parts of
+-- the OpenGL state. Note that state variables are not neccessarily writable or
+-- readable, they may come in read-only or write-only flavours, too. As a very
+-- simple example for a state variable, consider an explicitly allocated memory
+-- buffer. This buffer can easily be converted into a 'StateVar':
+--
+-- @
+-- makeStateVarFromPtr :: Storable a => Ptr a -> StateVar a
+-- makeStateVarFromPtr p = makeStateVar (peek p) (poke p)
+-- @
+--
+-- The example below puts 11 into a state variable (i.e. into the buffer),
+-- increments the contents of the state variable by 22, and finally prints the
+-- resulting content:
+--
+-- @
+--   do p <- malloc :: IO (Ptr Int)
+--      let v = makeStateVarFromPtr p
+--      v $= 11
+--      v $~ (+ 22)
+--      x <- get v
+--      print x
+-- @
+--
+-- 'IORef's are state variables, too, so an example with them looks extremely
+-- similiar:
+--
+-- @
+--   do v <- newIORef (0 :: Int)
+--      v $= 11
+--      v $~ (+ 22)
+--      x <- get v
+--      print x
+-- @
+--------------------------------------------------------------------------------
+
+module Data.StateVar (
+   -- * Readable State Variables
+   HasGetter(..),
+   GettableStateVar, makeGettableStateVar,
+   -- * Writable State Variables
+   HasSetter(..),
+   SettableStateVar, makeSettableStateVar,
+   -- * General State Variables
+   StateVar, makeStateVar,
+   -- * Utility Functions
+   ($~), ($=!), ($~!)
+) where
+
+import Data.IORef ( IORef, readIORef, writeIORef )
+
+--------------------------------------------------------------------------------
+
+infixr 2 $=
+
+--------------------------------------------------------------------------------
+
+-- | The class of all readable state variables.
+class HasGetter g where
+   -- | Read the value of a state variable.
+   get :: g a -> IO a
+
+instance HasGetter IORef where
+   get = readIORef
+
+-- | A concrete implementation of a read-only state variable, carrying an IO
+-- action to read the value.
+newtype GettableStateVar a = GettableStateVar (IO a)
+
+instance HasGetter GettableStateVar where
+   get (GettableStateVar g) = g
+
+-- | Construct a 'GettableStateVar' from an IO action.
+makeGettableStateVar :: IO a -> GettableStateVar a
+makeGettableStateVar = GettableStateVar
+
+--------------------------------------------------------------------------------
+
+-- | The class of all writable state variables.
+class HasSetter s where
+   -- | Write a new value into a state variable.
+   ($=) :: s a -> a -> IO ()
+
+instance HasSetter IORef where
+   ($=) = writeIORef
+
+-- | A concrete implementation of a write-only state variable, carrying an IO
+-- action to write the new value.
+newtype SettableStateVar a = SettableStateVar (a -> IO ())
+
+instance HasSetter SettableStateVar where
+   ($=) (SettableStateVar s) a = s a
+
+-- | Construct a 'SettableStateVar' from an IO action.
+makeSettableStateVar :: (a -> IO ()) -> SettableStateVar a
+makeSettableStateVar = SettableStateVar
+
+--------------------------------------------------------------------------------
+
+-- | A concrete implementation of a readable and writable state variable,
+-- carrying one IO action to read the value and another IO action to write the
+-- new value.
+data StateVar a =
+   StateVar (GettableStateVar a) (SettableStateVar a)
+
+instance HasGetter StateVar where
+   get (StateVar g _) = get g
+
+instance HasSetter StateVar where
+   ($=) (StateVar _ s) a = s $= a
+
+-- | Construct a 'StateVar' from two IO actions, one for reading and one for
+-- writing.
+makeStateVar :: IO a -> (a -> IO ()) -> StateVar a
+makeStateVar g s = StateVar (makeGettableStateVar g) (makeSettableStateVar s)
+
+--------------------------------------------------------------------------------
+
+-- | A modificator convenience function, transforming the contents of a state
+-- variable with a given funtion.
+
+($~) :: (HasGetter v, HasSetter v) => v a -> (a -> a) -> IO ()
+v $~ f = do
+   x <- get v
+   v $= f x
+
+-- | A variant of '$=' which is strict in the value to be set.
+($=!) :: HasSetter s => s a -> a -> IO ()
+v $=! x = x `seq` v $= x
+
+-- | A variant of '$~' which is strict in the transformed value.
+($~!) :: (HasGetter v, HasSetter v) => v a -> (a -> a) -> IO ()
+v $~! f = do
+   x <- get v
+   v $=! f x
