diff --git a/Data/Refcount.hs b/Data/Refcount.hs
new file mode 100644
--- /dev/null
+++ b/Data/Refcount.hs
@@ -0,0 +1,39 @@
+module Data.Refcount ( Refcount (..)
+                     , refcounted
+                     , insertRef
+                     , deleteRef
+                     , removeRef
+                     ) where
+
+import Control.Applicative ((<$>))
+import Data.Monoid
+import Data.Hashable
+import Data.HashMap.Strict as HashMap
+
+-- | Maintain a collection of objects with duplication counts.
+newtype Refcount a = Refcount { unRefcount :: HashMap a Int }
+
+instance (Hashable a, Eq a) => Monoid (Refcount a) where
+  mempty = Refcount empty
+  mappend (Refcount a) (Refcount b) = Refcount $ unionWith (+) a b
+
+-- | Retrieve the refcounted objects.
+refcounted :: Refcount a -> [a]
+refcounted = keys . unRefcount
+
+-- | Insert an object and increment its count.
+insertRef :: (Hashable a, Eq a) => a -> Refcount a -> Refcount a
+insertRef a (Refcount m) = Refcount $ insertWith (+) a 1 m
+
+-- | Remove a reference to an element and decrease its count, possibly removing it from the set.
+-- Returns @Nothing@ if the element wasn't found, or @Just set@.
+deleteRef :: (Hashable a, Eq a) => a -> Refcount a -> Maybe (Refcount a)
+deleteRef a r = snd <$> removeRef a r
+
+-- | Remove a reference to an element and decrease its count, possibly removing it from the set.
+-- Returns @Nothing@ if the element wasn't found, or @Just (wasRemoved, set)@.
+removeRef :: (Hashable a, Eq a) => a -> Refcount a -> Maybe (Bool, Refcount a)
+removeRef a (Refcount m) = fmap decRef $ HashMap.lookup a m
+  where decRef count = if count > 1
+                       then (False, Refcount $ adjust (subtract 1) a m)
+                       else (True, Refcount $ delete a m)
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/refcount.cabal b/refcount.cabal
new file mode 100644
--- /dev/null
+++ b/refcount.cabal
@@ -0,0 +1,24 @@
+name:               refcount
+version:            0.0.0
+synopsis:           Container with element counts
+category:           Data
+license:            MIT
+author:             Ben Foppa
+stability:          Experimental
+homepage:           https://github.com/RobotGymnast/refcount
+maintainer:         benjamin.foppa@gmail.com
+build-type:         Simple
+cabal-version:      >= 1.9.2
+
+library
+    hs-source-dirs:   .
+    ghc-options:      -Wall -threaded -rtsopts=all
+    exposed-modules:  Data.Refcount
+
+    build-depends: base == 4.*
+                 , hashable == 1.2.1.*
+                 , unordered-containers == 0.2.4.*
+
+source-repository head
+  type: git
+  location: https://github.com/RobotGymnast/refcount
