diff --git a/Data/FingerTree/PSQueue.hs b/Data/FingerTree/PSQueue.hs
new file mode 100644
--- /dev/null
+++ b/Data/FingerTree/PSQueue.hs
@@ -0,0 +1,186 @@
+{-# LANGUAGE MultiParamTypeClasses,
+             FlexibleInstances,
+             GeneralizedNewtypeDeriving,
+             NoMonomorphismRestriction #-}
+
+module Data.FingerTree.PSQueue
+  (Binding (..), PSQ, size, Data.FingerTree.PSQueue.null, Data.FingerTree.PSQueue.lookup,
+   empty, singleton, alter, Data.FingerTree.PSQueue.delete, adjust, adjustWithKey,
+   update, updateWithKey, toList, keys, fromList, fromAscList, minView,
+   findMin, deleteMin, range, atMost, Data.FingerTree.PSQueue.foldr,
+   Data.FingerTree.PSQueue.foldl) where
+
+import qualified Data.Foldable as F
+import qualified Data.FingerTree as FT
+import Data.FingerTree (FingerTree, ViewL (..), (<|), (|>),
+                        Measured (..), split, viewl, (><))
+import Data.Monoid
+import Data.Ord
+import Data.List
+
+data Prio k a = Prio (Binding k a) | PMax
+  deriving (Eq, Ord, Show)
+
+instance (Ord a) => Monoid (Prio k a)
+  where mempty = PMax
+        mappend PMax y = y
+        mappend x PMax = x
+        mappend a@(Prio (u :-> x)) b@(Prio (v :-> y)) = if x <= y then a else b
+
+data Key a = NoKey | Key a
+  deriving (Eq, Ord, Show)
+
+instance Monoid (Key k)
+  where mempty = NoKey
+        mappend x NoKey = x
+        mappend x y     = y
+
+geqKey k NoKey = False
+geqKey k (Key k') = k >= k'
+
+data Binding k p = k :-> p
+  deriving (Eq, Ord, Show)
+
+data KPS k p = KPS { kpsKey  :: !(Key k),
+                     kpsPrio :: !(Prio k p),
+                     kpsSize :: !(Sum Int) }
+  deriving (Show)
+
+instance Eq k => Eq (KPS k p) where
+  x == y = kpsKey x == kpsKey y
+
+instance Ord k => Ord (KPS k p) where
+  compare = comparing kpsKey
+
+instance (Ord p) => Monoid (KPS k p)
+  where mempty = KPS mempty mempty mempty
+        mappend (KPS k p s) (KPS k' p' s') = KPS (mappend k k')
+                                                 (mappend p p')
+                                                 (mappend s s')
+
+
+instance (Ord k, Ord p) => Measured (KPS k p) (Binding k p)
+  where measure a@(k :-> p) = KPS (Key k) (Prio a) (Sum 1)
+
+newtype PSQ k p = PSQ (FingerTree (KPS k p) (Binding k p))
+  deriving (Eq, Ord, Show, Measured (KPS k p))
+
+-- | O(1). The number of bindings in a queue.
+size :: (Ord k, Ord p) => PSQ k p -> Int
+size = getSum . kpsSize . measure
+
+-- | O(1). Test if a queue is empty.
+null :: (Ord k, Ord p) => PSQ k p -> Bool
+null (PSQ q) = FT.null q
+
+-- | O(log n). Determine if a key is in the queue, and its priority.
+lookup :: (Ord k, Ord p) => k -> PSQ k p -> Maybe p
+lookup k (PSQ q) = let (u,v) = split ((>= Key k) . kpsKey) q
+                    in case viewl v of
+                         EmptyL -> Nothing
+                         (k' :-> p) :< v' | k == k'   -> Just p
+                                          | otherwise -> Nothing
+
+-- | O(1). The empty queue.
+empty :: (Ord k, Ord p) => PSQ k p
+empty = PSQ (FT.empty)
+
+-- | O(1). Construct a queue with a single key/priority binding.
+singleton :: (Ord k, Ord p) => k -> p -> PSQ k p
+singleton k p = PSQ (FT.singleton (k :-> p))
+
+-- | O(log n). Alters a priority search queue such that @lookup k (alter f k q) = f (lookup k q)@. This can be used to insert, delete,
+-- or update a priority in a queue.
+alter :: (Ord k, Ord p) => (Maybe p -> Maybe p) -> k -> PSQ k p -> PSQ k p
+alter f k (PSQ q) =
+  PSQ $ let (u,v) = split (geqKey k . kpsKey) q
+         in case viewl v of
+              EmptyL -> case f Nothing of
+                           Nothing -> q
+                           Just p  -> q |> (k :-> p)
+              (k' :-> p') :< v'
+                | k == k'   -> case f (Just p') of
+                                 Nothing -> u >< v'
+                                 Just p  -> u >< ((k :-> p') <| v')
+                | otherwise -> case f Nothing of
+                                 Nothing -> u >< v
+                                 Just p  -> u >< ((k :-> p) <| v)
+
+-- | O(log n). Delete a key from a queue.
+delete :: (Ord k, Ord p) => k -> PSQ k p -> PSQ k p
+delete = alter (const Nothing)
+
+-- | O(log n). Adjust the priority of a key in the queue, provided that key exists.
+adjust :: (Ord k, Ord p) => (p -> p) -> k -> PSQ k p -> PSQ k p
+adjust f = alter (fmap f)
+
+-- | O(log n). Adjust the priority of a key in the queue, provided that key exists, according to a function which additionally takes
+-- the key as a parameter.
+adjustWithKey :: (Ord k, Ord p) => (k -> p -> p) -> k -> PSQ k p -> PSQ k p
+adjustWithKey f k = adjust (f k) k
+
+-- | O(log n). Update or delete a priority in the queue, provided that key exists.
+update :: (Ord k, Ord p) => (p -> Maybe p) -> k -> PSQ k p -> PSQ k p
+update f = alter (>>= f) 
+
+-- | O(log n). Update or delete a priority in the queue, provided that key exists, according to a function which additionally takes
+-- the key as a parameter.
+updateWithKey :: (Ord k, Ord p) => (k -> p -> Maybe p) -> k -> PSQ k p -> PSQ k p
+updateWithKey f k = update (f k) k
+
+-- | O(n). Flatten a queue into a list of bindings.
+toList :: (Ord k, Ord p) => PSQ k p -> [Binding k p]
+toList (PSQ q) = F.toList q
+
+-- | O(n). Extract the list of keys of a queue.
+keys :: (Ord k, Ord p) => PSQ k p -> [k]
+keys = map (\(k :-> p) -> k) . toList
+
+-- | O(n log n). Construct a queue from a list of bindings.
+fromList :: (Ord k, Ord p) => [Binding k p] -> PSQ k p
+fromList = PSQ . FT.fromList . sort
+
+-- | O(n log n). Contstruct a queue from an already ascending list of bindings. Does not check that the list is sorted.
+fromAscList :: (Ord k, Ord p) => [Binding k p] -> PSQ k p
+fromAscList = PSQ . FT.fromList
+
+-- | O(log n). Split a queue into the element with minimum priority, and the remainder.
+minView :: (Ord k, Ord p) => PSQ k p -> Maybe (Binding k p, PSQ k p)
+minView (PSQ q) =
+  let minPrio = kpsPrio . measure $ q
+      (u,v) = split ((== minPrio) . kpsPrio) q
+   in case viewl v of
+        EmptyL -> Nothing
+        ((k :-> p) :< v') -> Just (k :-> p, PSQ (u >< v'))
+
+-- | O(1). Find the binding with minimum priority in a queue.
+findMin :: (Ord k, Ord p) => PSQ k p -> Maybe (Binding k p)
+findMin q = case kpsPrio . measure $ q of
+                    PMax   -> Nothing
+                    Prio b -> Just b
+
+-- | O(log n). Delete the key with minimum priority from a queue.
+deleteMin :: (Ord k, Ord p) => PSQ k p -> PSQ k p
+deleteMin q = maybe q id . fmap snd . minView $ q
+
+-- | O(log n). The expression @range (l,u) q@ selects the keys k from q where @l <= k@ and @k <= u@.
+range :: (Ord k, Ord p) => (k, k) -> PSQ k p -> PSQ k p
+range (l,u) (PSQ q) = PSQ (fst . split ((> Key u) . kpsKey) . snd . split ((>= Key l) . kpsKey) $ q)
+
+-- | O(r (log n)). Finds all the bindings in a queue whose priority is less than the given value.
+atMost :: (Ord k, Ord p) => p -> PSQ k p -> [Binding k p]
+atMost p (PSQ q) =
+  let less (Prio (k :-> p')) = p' < p
+      (u,v) = split (less . kpsPrio) q
+   in case viewl v of
+        EmptyL    -> []
+        (b :< v') -> b : atMost p (PSQ v')
+
+-- | Right fold over the list of bindings in a queue. 
+foldr :: (Ord k, Ord p) => (Binding k p -> b -> b) -> b -> PSQ k p -> b
+foldr f z = Prelude.foldr f z . toList
+
+-- | Left fold over the list of bindings in a queue.
+foldl :: (Ord k, Ord p) => (b -> Binding k p -> b) -> b -> PSQ k p -> b
+foldl f z = Prelude.foldl f z . toList
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2009, Cale Gibbard
+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 Cale Gibbard nor the
+      names of any contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY CALE GIBBARD ''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 CALE GIBBARD 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/fingertree-psqueue.cabal b/fingertree-psqueue.cabal
new file mode 100644
--- /dev/null
+++ b/fingertree-psqueue.cabal
@@ -0,0 +1,20 @@
+name:                fingertree-psqueue
+version:             0.1
+cabal-version:       >= 1.2
+build-type:          Simple
+
+license:             BSD3
+license-file:        LICENSE
+copyright:           (c) 2009 Cale Gibbard
+author:              Cale Gibbard
+maintainer:          cgibbard@gmail.com
+stability:           experimental
+synopsis:            Implementation of priority search queues as finger trees.
+category:            Data Structures
+-- tested-with:         ghc-6.10.3
+description:         An implementation of priority search queues: a datastructure holding key/priority bindings having fast
+                     operations both for extracting the element with minimum priority and for modifying and looking up elements
+                     by key.
+library
+  exposed-modules:   Data.FingerTree.PSQueue
+  build-depends:     base<=4,fingertree 
