diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,25 @@
+The following license covers this documentation, and the source code, except
+where otherwise indicated.
+
+Copyright 2012, Myles C. Maxfield. 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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "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 HOLDERS 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/Network/PublicSuffixList/Create.hs b/Network/PublicSuffixList/Create.hs
new file mode 100644
--- /dev/null
+++ b/Network/PublicSuffixList/Create.hs
@@ -0,0 +1,70 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+
+{-|
+This script parses the public suffix list, and constructs a data structure which can
+be used with the isSuffix function in Lookup.hs. It exports a GSink which produces
+the opaque 'DataStructure' and can be fed any Source as input.
+
+This makes an few assumption about the information in the public suffix list:
+namely, that no rule is a suffix of another rule. For example, if there is a rule
+abc.def.ghi
+then then is no other rule
+def.ghi
+or
+!def.ghi
+
+The actual data structure involved here is a tree where the nodes have no value and
+the edges are DNS labels. There are two trees: one to handle the exception rules,
+and one to handle the regular rules.
+-}
+
+module Network.PublicSuffixList.Create (PublicSuffixListException, sink) where
+
+import           Control.Exception
+import qualified Data.ByteString      as BS
+import qualified Data.Conduit         as C
+import qualified Data.Conduit.List    as CL
+import qualified Data.Conduit.Text    as CT
+import           Data.Default
+import qualified Data.Map             as M
+import qualified Data.Text            as T
+import           Data.Typeable
+import           Text.IDNA
+
+import           Network.PublicSuffixList.Internal.Types
+
+data PublicSuffixListException = PublicSuffixListException
+  deriving (Show, Typeable)
+
+instance Exception PublicSuffixListException
+
+insert :: (Ord e) => Tree e -> [e] -> Tree e
+insert _ [] = def
+insert t (p : ps) = case M.lookup p $ children t of
+  Nothing -> t { children = M.insert p (insert def ps) $ children t }
+  Just l -> t { children = M.insert p (insert l ps) $ children t }
+
+foldingFunction :: DataStructure -> T.Text -> DataStructure
+foldingFunction d@(rules, exceptions) s'
+  | T.null s = d
+  | T.take 2 s == "//" = d
+  | T.head s == '!' = (rules, insert exceptions $ labelList $ T.tail s)
+  | otherwise = (insert rules $ labelList s, exceptions)
+  where ss = filter (not . T.null) $ T.words s'
+        s
+          | null ss = ""
+          | otherwise = head ss
+        labelList = reverse . map internationalize . T.split (== '.')
+        internationalize str
+          | str == "*" = str
+          | otherwise = case toASCII False True $ T.toLower str of
+                          Just x -> x
+                          Nothing -> throw PublicSuffixListException
+
+{-
+Generate the opaque 'DataStructure'
+-}
+sink :: C.MonadThrow m => C.GSink BS.ByteString m DataStructure
+sink = CT.decode CT.utf8 C.>+> CT.lines C.>+> CL.fold foldingFunction def
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,4 @@
+#! /usr/bin/env runhaskell
+
+> import Distribution.Simple
+> main = defaultMain
diff --git a/publicsuffixlistcreate.cabal b/publicsuffixlistcreate.cabal
new file mode 100644
--- /dev/null
+++ b/publicsuffixlistcreate.cabal
@@ -0,0 +1,29 @@
+name:            publicsuffixlistcreate
+version:         0.0.1
+license:         BSD3
+license-file:    LICENSE
+author:          Myles C. Maxfield <myles.maxfield@gmail.com>
+maintainer:      Myles C. Maxfield <myles.maxfield@gmail.com>
+synopsis:        Create the publicsuffixlist package
+description:     Create the publicsuffixlist package. This is broken out into its own package so users of the publicsuffixlist package don't have to depend on ICU.
+category:        Network
+stability:       Experimental
+cabal-version:   >= 1.8
+build-type:      Simple
+homepage:        https://github.com/litherum/publicsuffixlist
+
+library
+    build-depends: base             >= 4     && < 5
+                 , containers
+                 , data-default
+                 , bytestring       >= 0.9
+                 , idna             >= 0.1.2 && < 1.0
+                 , text             >= 0.11
+                 , conduit          >= 0.5.0 && < 0.6.0
+                 , publicsuffixlist >= 0.0.2 && < 0.1.0
+    exposed-modules: Network.PublicSuffixList.Create
+    ghc-options:     -Wall
+
+source-repository head
+  type:     git
+  location: git://github.com/litherum/publicsuffixlist.git
