diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,32 @@
+Copyright (c) 2010, Andreas Baldeau
+
+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 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 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/README b/README
new file mode 100644
--- /dev/null
+++ b/README
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,6 @@
+module Main where
+
+import Distribution.Simple
+
+main = defaultMain
+
diff --git a/examples/RegExp.hs b/examples/RegExp.hs
new file mode 100644
--- /dev/null
+++ b/examples/RegExp.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE
+        MultiParamTypeClasses,
+        TemplateHaskell,
+        UndecidableInstances
+  #-}
+
+module RegExp where
+
+import Prelude hiding (lookup)
+
+import Data.ListTrie.RegExp
+
+import Data.Bits
+
+import Data.KeyMap (empty, insert, toList)
+import qualified Data.KeyMap as KeyMap
+import Data.Derive.Trie
+
+$(deriveTrie [''Bool])
+
+toBits :: Int -> [Bool]
+toBits n = map (testBit n) [0..7]
+
+fromBits :: [Bool] -> Int
+fromBits bs = foldr (\ b n -> let n' = shiftL n 1
+                              in  if b then n' + 1 else n') 0 bs
+
+exampleTrie :: ListTrie BoolTrie Int
+exampleTrie = foldr (\ n -> insert (toBits n) n) empty [0..255]
+
+re1 = rep (sym True)
+re2 = rep (sym False)
+re3 = rep (sym True `seq_` sym False)
+re4 = rep anySym `seq_` sym False `seq` sym True `seq_` rep anySym
+re5 = sym True `seq_` rep anySym
+
diff --git a/regexp-tries.cabal b/regexp-tries.cabal
new file mode 100644
--- /dev/null
+++ b/regexp-tries.cabal
@@ -0,0 +1,58 @@
+Name:          regexp-tries
+Version:       0.1.0
+Stability:     Alpha
+Synopsis:      Regular Expressions on Tries.
+Description:   Regular Expressions on Tries.
+License:       BSD3
+License-File:  LICENSE
+Build-Type:    Simple
+Author:        Andreas Baldeau
+Maintainer:    Andreas Baldeau <andreas@baldeau.net>
+Homepage:      http://github.com/baldo/regexp-tries
+Bug-Reports:   http://github.com/baldo/regexp-tries/issues
+Category:      Data
+Tested-With:   GHC == 6.12.3
+Cabal-Version: >= 1.8
+
+Extra-Source-Files:
+    Setup.hs
+    README
+    examples/RegExp.hs
+
+Source-Repository head
+    Type:     git
+    Location: git://github.com/baldo/regexp-tries.git
+
+Library
+    Build-Depends:
+        base             == 4.*,
+        containers       == 0.3.*,
+        derive-trie      == 0.1.*,
+        template-haskell == 2.4.*,
+        weighted-regexp  >= 0.3.1 && <= 0.4
+
+    Ghc-Options:
+        -Wall
+
+    Hs-Source-Dirs:
+        src
+
+    Exposed-Modules:
+        Data.ListTrie
+        Data.ListTrie.RegExp
+        Data.ListTrie.RegExp.Weighted
+
+    Other-Modules:
+        Data.ListTrie.ListTrie
+        Data.ListTrie.RegExp.Common
+
+    Extensions:
+        FlexibleContexts
+        FlexibleInstances
+        FunctionalDependencies
+        MultiParamTypeClasses
+        OverlappingInstances
+        TemplateHaskell
+        TypeSynonymInstances
+        UndecidableInstances
+
diff --git a/src/Data/ListTrie.hs b/src/Data/ListTrie.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ListTrie.hs
@@ -0,0 +1,17 @@
+{- | This module provides 'StringTrie' and 'ListTrie' as an instance of
+     'KeyMap'.
+-}
+
+module Data.ListTrie
+    ( -- * Trie types
+      ListTrie
+    , StringTrie
+
+      -- * 'KeyMap' module providing Trie operations
+    , module Data.KeyMap
+    )
+where
+
+import Data.ListTrie.ListTrie
+import Data.KeyMap
+
diff --git a/src/Data/ListTrie/ListTrie.hs b/src/Data/ListTrie/ListTrie.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ListTrie/ListTrie.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE
+        MultiParamTypeClasses,
+        TemplateHaskell,
+        TypeSynonymInstances,
+        UndecidableInstances
+  #-}
+{-# OPTIONS_GHC
+        -fno-warn-missing-signatures
+        -fno-warn-unused-binds
+        -fno-warn-unused-matches
+  #-}
+
+-- Hidden module used for deriving Trie types.
+
+module Data.ListTrie.ListTrie
+    ( StringTrie (..)
+    , ListTrie (..)
+
+    , module KeyMap
+    )
+where
+
+import Data.Derive.Trie
+import Data.KeyMap
+import qualified Data.KeyMap as KeyMap
+
+$(deriveTrie [''String])
+
diff --git a/src/Data/ListTrie/RegExp.hs b/src/Data/ListTrie/RegExp.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ListTrie/RegExp.hs
@@ -0,0 +1,9 @@
+-- | This module reexports 'Data.ListTrie.RegExp.Weighted' for now.
+
+module Data.ListTrie.RegExp
+    ( module Data.ListTrie.RegExp.Weighted
+    )
+where
+
+import Data.ListTrie.RegExp.Weighted
+
diff --git a/src/Data/ListTrie/RegExp/Common.hs b/src/Data/ListTrie/RegExp/Common.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ListTrie/RegExp/Common.hs
@@ -0,0 +1,162 @@
+{-# LANGUAGE
+        FlexibleContexts,
+        FlexibleInstances,
+        FunctionalDependencies,
+        MultiParamTypeClasses
+  #-}
+
+{- | This module provides functionality that all regular expression
+     implementations share.
+-}
+
+module Data.ListTrie.RegExp.Common
+    ( WrapClass (..)
+
+    -- * Expression Type for Combinators
+    , Expr (..)
+    , ExprClass (..)
+
+    -- * Regular Expression Combinators
+    , complement
+    , intersection
+    , union
+
+    -- * Trie operations
+    , LookupRegExpClass (..)
+    , lookup
+    , delete
+
+    -- * Optimzation of combined Regular Expressions
+    , OptimizeClass (..)
+    , optimize
+    )
+where
+
+import Prelude hiding (lookup)
+import qualified Data.KeyMap as KM
+import Data.ListTrie.ListTrie hiding
+    ( delete
+    , intersection
+    , lookup
+    , union
+    )
+import Data.Map (Map)
+
+-- Wrapping and unwrapping of StringTrie ---------------------------------------
+
+{- | Allows the usage of 'StringTrie' and 'ListTrie' the same way.
+-}
+class (KeyMap [sym] map, KeyMap sym emap)
+   => WrapClass map emap sym | map -> emap where
+    wrap   :: ListTrie emap v -> map v
+    unwrap :: map v -> ListTrie emap v
+
+instance WrapClass StringTrie (Map Char) Char where
+    wrap   = StringTrie
+    unwrap = unStringTrie
+
+instance (KeyMap sym emap) => WrapClass (ListTrie emap) emap sym where
+    wrap   = id
+    unwrap = id
+
+-- Regular Expression Combinators ----------------------------------------------
+
+{- | Expressions may be build by using the combinators 'complement',
+     'intersection' and 'union'. They can then be used with 'lookup' and
+     'delete'.
+-}
+data Expr regexp = REExpr regexp
+                 | Complement (Expr regexp)
+                 | Intersection (Expr regexp) (Expr regexp)
+                 | Union (Expr regexp) (Expr regexp)
+
+-- | Allows to also use regular expressions directly instead of 'Expr' types.
+class ExprClass e regexp | e -> regexp where
+    toExpr :: e -> (Expr regexp)
+
+instance ExprClass (Expr regexp) regexp where
+    toExpr = id
+
+-- | Perform the operation with the complement of the expression.
+complement
+    :: ExprClass e regexp
+    => e        -- ^ an expression
+    -> Expr regexp -- ^ the complement
+complement = Complement . toExpr
+
+-- | Intersection of the result of two expressions.
+intersection
+    :: (ExprClass e1 regexp, ExprClass e2 regexp)
+    => e1
+    -> e2
+    -> Expr regexp
+intersection e1 e2 = Intersection (toExpr e1) (toExpr e2)
+
+-- | Union of the result of two expressions.
+union
+    :: (ExprClass e1 regexp, ExprClass e2 regexp)
+    => e1
+    -> e2
+    -> Expr regexp
+union e1 e2 = (Union (toExpr e1) (toExpr e2))
+
+-- Trie operations -------------------------------------------------------------
+
+class (WrapClass map emap sym, OptimizeClass regexp)
+   => LookupRegExpClass regexp map emap sym | regexp -> sym where
+    lookupRegExp
+        :: regexp
+        -> map v
+        -> map v
+    lookupComplement
+        :: regexp
+        -> map v
+        -> map v
+
+-- | Lookup the given expression in the given Trie and return a Trie of results.
+lookup
+    :: (LookupRegExpClass (regexp sym) map emap sym, ExprClass e (regexp sym))
+    => e     -- ^ expression to lookup
+    -> map v -- ^ Trie on wich to perform the lookup
+    -> map v -- ^ resulting Trie
+lookup = lookupExpr . optimize
+
+-- | Delete entries matching the expression from the given Trie.
+delete
+    :: (LookupRegExpClass (regexp sym) map emap sym, ExprClass e (regexp sym))
+    => e     -- ^ expression
+    -> map v -- ^ Trie to delete from
+    -> map v -- ^ Trie missing the entries that matched the expression.
+delete = lookupExpr . optimize . complement
+
+-- | Evaluates the given expression on the given Trie.
+lookupExpr
+    :: LookupRegExpClass (regexp sym) map emap sym
+    => Expr (regexp sym)
+    -> map v
+    -> map v
+lookupExpr (REExpr re)                  t = lookupRegExp re t
+lookupExpr (Complement (REExpr re))     t = lookupComplement re t
+lookupExpr (Complement (Complement e))  t = lookupExpr e t
+lookupExpr (Complement e)               t = difference t $ lookupExpr e t
+lookupExpr (Intersection e1 e2)         t = lookupExpr e2 (lookupExpr e1 t)
+lookupExpr (Union e1 e2)                t = KM.union t1 t2
+    where
+        t1 = lookupExpr e1 t
+        t2 = lookupExpr e2 t
+
+-- Optimzation of combined Regular Expressions ---------------------------------
+
+class OptimizeClass regexp where
+    -- | Optimize the given expression.
+    optimizeExpr
+        :: Expr regexp -- ^ expression
+        -> Expr regexp -- ^ optimized expression
+
+-- | Optimize the given expression.
+optimize
+    :: (ExprClass e regexp, OptimizeClass regexp)
+    => e           -- ^ expression
+    -> Expr regexp -- ^ optimized expression
+optimize = optimizeExpr . toExpr
+
diff --git a/src/Data/ListTrie/RegExp/Weighted.hs b/src/Data/ListTrie/RegExp/Weighted.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ListTrie/RegExp/Weighted.hs
@@ -0,0 +1,223 @@
+{-# LANGUAGE
+        FlexibleContexts,
+        FlexibleInstances,
+        FunctionalDependencies,
+        MultiParamTypeClasses,
+        OverlappingInstances,
+        UndecidableInstances
+  #-}
+{-# OPTIONS_GHC
+        -fno-warn-orphans
+  #-}
+
+{- | This module provides 'delete' and 'lookup' functions for 'StringTrie'
+     using regular expressions. The algorithm used is the one from the package
+    'weighted-regexp': <http://sebfisch.github.com/haskell-regexp/>.
+-}
+
+module Data.ListTrie.RegExp.Weighted
+    (
+    -- * Trie types
+      ListTrie
+    , StringTrie
+
+    -- * Construction of regular expressions
+    , RegExp
+
+    , eps
+    , char
+    , sym
+    , psym
+
+    , anySym
+    , noMatch
+
+    , alt
+    , seq_
+
+    , rep
+    , rep1
+    , opt
+    , brep
+
+    , perm
+
+    -- * Expression Type for Combinators
+    , Expr
+    , ExprClass
+
+    -- * Regular Expression Combinators
+    , complement
+    , intersection
+    , union
+
+    -- * Trie operations
+    , lookup
+    , delete
+
+    , lookupW
+    )
+where
+
+import Prelude hiding
+    ( lookup
+    , mod
+    , null
+    , pred
+    )
+import Data.ListTrie.ListTrie hiding
+    ( delete
+    , empty
+    , intersection
+    , lookup
+    , union
+    )
+import Data.ListTrie.RegExp.Common
+import Data.Maybe
+import Data.Semiring
+import Text.RegExp
+import Text.RegExp.Internal
+
+-- Storing weights within the Trie ---------------------------------------------
+
+class StoreWeights v w v' | v v' -> w where
+    store :: w -> v -> v'
+    select :: m v -> m v' -> m v'
+
+instance StoreWeights v Bool v where
+    store _ v = v
+    select m _ = m
+
+instance StoreWeights v w (v, w) where
+    store w v = (v, w)
+    select _ m = m
+
+-- Regular Expression lookup ---------------------------------------------------
+
+instance WrapClass map emap sym
+      => LookupRegExpClass (RegExp sym) map emap sym where
+    lookupRegExp     = lookupReW 0 True id  empty
+    lookupComplement = lookupReW 0 True not empty
+
+lookupReW
+    :: (WrapClass map emap sym, StoreWeights v w v', Weight sym sym w)
+    => Int
+    -> w
+    -> (w -> w)
+    -> (RegW w sym -> w)
+    -> RegExp sym
+    -> map v
+    -> map v'
+lookupReW n mark mod pred (RegExp re) t =
+    wrap $ lookupRe n mark mod pred re $ unwrap t
+
+lookupRe
+    :: (KeyMap sym map, StoreWeights v w v', Weight sym sym w)
+    => Int
+    -> w
+    -> (w -> w)
+    -> (RegW w sym -> w)
+    -> RegW w sym
+    -> ListTrie map v
+    -> ListTrie map v'
+lookupRe _ _    _   _    _  NoListTrie       = NoListTrie
+lookupRe n mark mod pred re t@(ListTrie tn tc)
+    | n > 0 && not (active re) =
+        if mod one' /= zero
+            then NoListTrie
+            else select t $ error "This should never haqppen!"
+                        -- (KM.map (store one') t)
+    | otherwise =
+        if isJust tn' || not (null tc')
+            then ListTrie tn' tc'
+            else NoListTrie
+    where
+        one' = one
+        tn'  = if w /= zero then fmap (store w) tn else Nothing
+        w    = mod $ pred re
+        tc'  = mapMaybeWithKey go tc
+
+        go c ts =
+            cleanup $ lookupRe (n + 1) zero mod final (shift mark (reg re) c) ts
+
+        cleanup ts
+            | null ts   = Nothing
+            | otherwise = Just ts
+
+-- Expression instances --------------------------------------------------------
+
+instance ExprClass (RegExp sym) (RegExp sym) where
+    toExpr = REExpr
+
+instance ExprClass e (RegExp Char) => Show e where
+    showsPrec _ e =
+        case toExpr e of
+            REExpr re ->
+                showString "(RegExp<" . shows re . showString ">)"
+            Complement e' ->
+                showString "(Complement " . shows e' . showString ")"
+            Intersection e1 e2 ->
+                showString "(Intersection " . shows e1 . showChar ' '
+                                            . shows e2 . showString ")"
+            Union e1 e2 ->
+                showString "(Union" . shows e1 . showChar ' '
+                                    . shows e2 . showString ")"
+
+-- Trie operations -------------------------------------------------------------
+
+{- | Lookup the given regular expression in the Trie and return a Trie of
+     results, containing also the calculated weights.
+
+     Note: As weights don't make much sense with delete (would all be 'zero'),
+     there is no 'deleteW'.
+
+     Note: Since there doesn't seem to be a way to efficiently allow combining
+     of weighted regular expressions, there are no combinators for this for now.
+-}
+lookupW
+    :: (WrapClass map emap sym, StoreWeights v w (v, w), Weight sym sym w)
+    => RegExp sym
+    -> map v
+    -> map (v, w)
+lookupW (RegExp re) t = wrap $ lookupRe 0 one id empty (weighted re) $ unwrap t
+
+-- Optimzation of combined Regular Expressions ---------------------------------
+
+instance OptimizeClass (RegExp sym) where
+    optimizeExpr e@(REExpr _) =
+        e
+
+    optimizeExpr (Complement e) =
+        case optimizeExpr e of
+            (Complement e') ->
+                e'
+
+            (Intersection (Complement e1') (Complement e2')) ->
+                Union e1' e2'
+
+            e' ->
+                Complement e'
+
+    optimizeExpr (Intersection e1 e2) =
+        case (optimizeExpr e1, optimizeExpr e2) of
+            (e1', e2') ->
+                Intersection (optimizeExpr e1') (optimizeExpr e2')
+
+    optimizeExpr (Union e1 e2) =
+        case (optimizeExpr e1, optimizeExpr e2) of
+            (REExpr r1, REExpr r2) ->
+                REExpr $ r1 `alt` r2
+
+            -- Complement of regular expressions is cheap.
+            (e1'@(Complement (REExpr _)), e2') ->
+                Union e1' e2'
+            (e1', e2'@(Complement (REExpr _))) ->
+                Union e1' e2'
+
+            -- Evaluating Complement once is cheaper than doing it twice.
+            (Complement e1', Complement e2') ->
+                Complement $ Intersection e1' e2'
+
+            (e1', e2') ->
+                Union e1' e2'
+
