diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2011, Henning Thielemann
+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 Henning Thielemann nor the names of other
+      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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#! /usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/enumset.cabal b/enumset.cabal
new file mode 100644
--- /dev/null
+++ b/enumset.cabal
@@ -0,0 +1,36 @@
+Name:             enumset
+Version:          0.0
+License:          BSD3
+License-File:     LICENSE
+Author:           Henning Thielemann <haskell@henning-thielemann.de>
+Maintainer:       Henning Thielemann <haskell@henning-thielemann.de>
+Homepage:         http://code.haskell.org/~thielema/enumset/
+Category:         Data, Foreign
+Synopsis:         Sets of enumeration values represented by machine words
+Description:
+  With this package you can create a type safe interface to flag sets.
+  It is intended for interfacing to C libraries via FFI,
+  where Word8, Word16, or Word32 types are commonly used to store bit vectors.
+  E.g. the type @EnumSet Word16 Ordering@
+  represents a flag set stored in a Word16
+  that supports the flags @LT@, @EQ@, @GT@.
+  .
+  This package is similar to the @bitset@ package
+  the @Data.Edison.Coll.EnumSet@ module in the edison package,
+  however our implementation allows you to choose the embedding type
+  and thus the maximum size of the set.
+-- Portability:      Haskell98
+Cabal-Version:    >=1.2
+Tested-With:      GHC==6.10.4, GHC==6.12.3
+Build-Type:       Simple
+
+Library
+  Build-Depends:
+    storable-record >=0.0.1 && <0.1,
+    base >= 4 && <6
+
+  GHC-Options:      -Wall
+  Hs-Source-Dirs:   src
+  Exposed-Modules:
+    Data.EnumSet
+    Data.EnumSet.PackedEnum
diff --git a/src/Data/EnumSet.hs b/src/Data/EnumSet.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/EnumSet.hs
@@ -0,0 +1,110 @@
+{- |
+Similar to Data.Edison.Coll.EnumSet
+but it allows to choose the underlying type for bit storage.
+This is really a low-level module for type-safe foreign function interfaces.
+-}
+module Data.EnumSet (
+   T(Cons, decons),
+   fromEnum,
+   fromEnums,
+   toEnums,
+   intToEnums,
+   empty,
+   (.&.),
+   (.|.),
+   xor,
+   unions,
+   get,
+   put,
+   set,
+   clear,
+   flip,
+   fromBool,
+   ) where
+
+import qualified Data.Bits as B
+import Data.Bits (Bits, )
+
+import qualified Foreign.Storable.Newtype as Store
+import Foreign.Storable (Storable(..), )
+
+import qualified Prelude as P
+import Prelude hiding (fromEnum, toEnum, flip, )
+
+
+newtype T word enum = Cons {decons :: word}
+   deriving (Eq)
+
+instance (Storable word, Enum enum) => Storable (T word enum) where
+   sizeOf = Store.sizeOf decons
+   alignment = Store.alignment decons
+   peek = Store.peek Cons
+   poke = Store.poke decons
+
+
+fromEnum :: (Enum a, Bits w) => a -> T w a
+fromEnum = Cons . B.bit . P.fromEnum
+
+fromEnums :: (Enum a, Bits w) => [a] -> T w a
+fromEnums = Cons . foldl B.setBit 0 . map P.fromEnum
+
+toEnums :: (Enum a, Bits w) => T w a -> [a]
+toEnums =
+   map fst . filter (P.flip B.testBit 0 . snd) .
+   zip [P.toEnum 0 ..] . iterate (P.flip B.shiftR 1) .
+   decons
+
+intToEnums :: (Enum a, Integral w) => T w a -> [a]
+intToEnums =
+   map fst . filter (odd . snd) .
+   zip [P.toEnum 0 ..] . iterate (P.flip div 2) .
+   decons
+
+
+empty :: (Enum a, Bits w) => T w a
+empty = Cons 0
+
+
+{-# INLINE lift2 #-}
+lift2 :: (w -> w -> w) -> (T w a -> T w a -> T w a)
+lift2 f (Cons x) (Cons y) = Cons (f x y)
+
+-- fixities like in Data.Bits
+infixl 7 .&.
+infixl 5 .|.
+
+(.&.), (.|.), xor :: (Enum a, Bits w) => T w a -> T w a -> T w a
+(.&.) = lift2 (B..&.)
+(.|.) = lift2 (B..|.)
+xor   = lift2 B.xor
+
+unions :: (Enum a, Bits w) => [T w a] -> T w a
+unions = foldl (.|.) empty
+
+
+get :: (Enum a, Bits w) => a -> T w a -> Bool
+get n = P.flip B.testBit (P.fromEnum n) . decons
+
+put :: (Enum a, Bits w) => a -> Bool -> T w a -> T w a
+put n b s =
+   fromBool n b .|. clear n s
+
+
+{-# INLINE lift1 #-}
+lift1 ::
+   (Enum a, Bits w) =>
+   (w -> Int -> w) -> (a -> T w a -> T w a)
+lift1 f n (Cons vec) = Cons (f vec (P.fromEnum n))
+
+set :: (Enum a, Bits w) => a -> T w a -> T w a
+set = lift1 B.setBit
+
+clear :: (Enum a, Bits w) => a -> T w a -> T w a
+clear = lift1 B.clearBit
+
+flip :: (Enum a, Bits w) => a -> T w a -> T w a
+flip = lift1 B.complementBit
+
+fromBool :: (Enum a, Bits w) => a -> Bool -> T w a
+fromBool n b =
+   Cons (B.shiftL (fromIntegral $ P.fromEnum b) (P.fromEnum n))
diff --git a/src/Data/EnumSet/PackedEnum.hs b/src/Data/EnumSet/PackedEnum.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/EnumSet/PackedEnum.hs
@@ -0,0 +1,55 @@
+{- |
+Extract and inject an Enum value into an EnumSet.
+-}
+module Data.EnumSet.PackedEnum (T(Cons), unpack, pack, clear, put, ) where
+
+import qualified Data.EnumSet as ES
+
+import qualified Data.Bits as B
+import Data.Bits (Bits, (.&.), )
+
+
+{- |
+@ T w a b@ describes a contiguous set of bit indices into the word type @w@
+where the indices are of type @a@ and the set of indices represent a value of type @b@.
+-}
+data T w a b = Cons w Int
+
+{- |
+Extract an enumeration value from the specified index set.
+-}
+unpack ::
+   (Integral w, Bits w, Enum a, Enum b) =>
+   T w a b -> ES.T w a -> b
+unpack (Cons mask pos) =
+   toEnum . fromIntegral . (mask .&.) .
+   flip B.shiftR pos . ES.decons
+
+{- |
+Create an enumeration set, where an value of type @b@
+is placed at the specified indices.
+-}
+pack ::
+   (Bits w, Enum a, Enum b) =>
+   T w a b -> b -> ES.T w a
+pack (Cons mask pos) =
+   ES.Cons . flip B.shiftL pos .
+   (mask .&.) . fromIntegral . fromEnum
+
+{- |
+Clear all bits at the specified indices.
+-}
+clear ::
+   (Bits w, Enum a, Enum b) =>
+   T w a b -> ES.T w a -> ES.T w a
+clear (Cons mask pos) =
+   ES.Cons . (B.complement (B.shiftL mask pos) .&.) . ES.decons
+
+{- |
+Overwrite an enumset at the specified indices with the value of type @b@.
+-}
+put ::
+   (Bits w, Enum a, Enum b) =>
+   T w a b -> b -> ES.T w a -> ES.T w a
+put set x =
+   (pack set x ES..|.) . clear set
