diff --git a/SmartGroup.hs b/SmartGroup.hs
--- a/SmartGroup.hs
+++ b/SmartGroup.hs
@@ -1,19 +1,30 @@
-module SmartGroup (groupAll, groupNum, groupLog) where
+{-# LANGUAGE TypeSynonymInstances #-}
+module SmartGroup (Splittable, groupAll, groupNum, groupLog) where
 import Data.Heap as Heap
 import Data.Set as Set
 import Data.Map as Map
 import Data.Monoid
+import Data.Char
+import qualified Data.ByteString.Char8 as S
+import qualified Data.ByteString.Lazy.Char8 as L
 import Data.Ord
 
-data StringL = StringL {str :: String, count :: Int} deriving (Eq, Show)
-instance Ord StringL where compare (StringL i a) (StringL x b) = compare a b `mappend` compare i x
-data SizeMap a = Unsplittable (Set a) | Splittable (Map StringL (Set a)) deriving (Eq, Show)
-instance Ord s => Ord (SizeMap s) where
+class Ord a => Splittable a where wordsOf :: a -> [a]
+instance Splittable String where wordsOf = Prelude.filter ((>3) . length) . words
+instance Splittable L.ByteString where
+         wordsOf = Prelude.filter ((>3) . L.length) . L.splitWith isSpace
+instance Splittable S.ByteString where
+         wordsOf = Prelude.filter ((>3) . S.length) . S.splitWith isSpace
+
+data StringL a = StringL {str :: a, count :: Int} deriving (Eq, Show)
+instance Ord a => Ord (StringL a) where compare (StringL i a) (StringL x b) = compare a b `mappend` compare i x
+data SizeMap s a = Unsplittable (Set a) | Splittable (Map (StringL s) (Set a)) deriving (Eq, Show)
+instance (Ord s, Ord a) => Ord (SizeMap s a) where
          compare (Splittable a) (Splittable b) = compare (Map.size a) (Map.size b)
          compare (Unsplittable a) (Unsplittable b) = compare a b
          compare (Unsplittable _) (Splittable _) = LT
          compare (Splittable _) (Unsplittable _) = GT
-type WordAssoc a = MaxHeap (SizeMap a)
+type WordAssoc s a = MaxHeap (SizeMap s a)
 
 toSet (Unsplittable x) = x
 toSet (Splittable x) = Set.unions (Map.elems x)
@@ -21,11 +32,11 @@
 intLog :: Int -> Int
 intLog = truncate . logBase 2 . fromIntegral
 
-groupWith :: Ord a => (Int -> WordAssoc a -> WordAssoc a) -> Int -> (a -> String) -> [a] -> [[a]]
+groupWith :: (Ord a, Splittable s) => (Int -> WordAssoc s a -> WordAssoc s a) -> Int -> (a -> s) -> [a] -> [[a]]
 groupWith f i c = mkList . f i . mkAssoc . mkMap c
 
 -- | Divide list into as many groups as possible
-groupAll :: Ord a => Int -> (a -> String) -> [a] -> [[a]]
+groupAll :: (Ord a, Splittable s) => Int -> (a -> s) -> [a] -> [[a]]
 groupAll = groupWith $ \i x->
          let cycleSplit n = case splitIt i n of
                   (Just a) -> cycleSplit a
@@ -33,7 +44,7 @@
          in cycleSplit x
 
 -- | Divide list into about n different groups
-groupNum :: Ord a => Int -> Int -> (a -> String) -> [a] -> [[a]]
+groupNum :: (Ord a, Splittable s) => Int -> Int -> (a -> s) -> [a] -> [[a]]
 groupNum i = groupWith $ \x->
          let splitTimes n m =
                 if Heap.size m >= n then m else
@@ -44,38 +55,42 @@
 
 -- | Divide list into groups such that the amount of groups
 --   equals the log of the number of elements
-groupLog :: Ord a => Int -> (a -> String) -> [a] -> [[a]]
+groupLog :: (Ord a, Splittable s) => Int -> (a -> s) -> [a] -> [[a]]
 groupLog i f s = groupNum (intLog (length s)) i f s
 
-mkMap :: Ord a => (a -> String) -> [a] -> Map String (Set a)
+mkMap :: (Ord a, Splittable s) => (a -> s) -> [a] -> Map s (Set a)
 mkMap f = foldl (\m x->
-        foldl (\m' i-> if length i > 3
-              then Map.alter (Just . maybe (Set.singleton x) (Set.insert x)) i m' else m')
-        m (words $ f x)) Map.empty
+        foldl (\m' i-> Map.alter (Just . maybe (Set.singleton x) (Set.insert x)) i m')
+        m (wordsOf $ f x)) Map.empty
 
-mkAssoc :: Ord a => Map String (Set a) -> MaxHeap (SizeMap a)
+mkAssoc :: (Ord a, Splittable s) => Map s (Set a) -> MaxHeap (SizeMap s a)
 mkAssoc m = Heap.singleton . Splittable . Map.mapKeys (\k-> StringL k (Set.size (m Map.! k))) $ m
 
-splitIt :: Ord a => Int -> WordAssoc a -> Maybe (WordAssoc a)
+splitIt :: (Ord a, Splittable s) => Int -> WordAssoc s a -> Maybe (WordAssoc s a)
 splitIt i s = case Heap.view s of
+         Nothing -> Nothing
          (Just ((Unsplittable _),_)) -> Nothing
-         (Just ((Splittable x),xs)) ->
-               let
-                  (Just (as,b)) = Map.maxView x
-                  x1 = sizeMap i $ flip Map.mapMaybe b $ \n->
+         (Just ((Splittable x),xs)) -> do
+               (as,b) <- Map.maxView x
+               x1 <- sizeMap i $ flip Map.mapMaybe b $ \n->
                       let m = Set.difference n as
                       in if Set.null m then Nothing else Just m
-                  x2 = sizeMap i $ flip Map.mapMaybe b $ \n->
+               x2 <- sizeMap i $ flip Map.mapMaybe b $ \n->
                       let m = Set.intersection n as
                       in if Set.null m then Nothing else Just m
-                  x3 = as Set.\\ (Set.unions (Map.elems b))
-               in Just $ (if Set.null x3 then id else Heap.insert (Unsplittable x3)) $
+               let x3 = as Set.\\ (Set.unions (Map.elems b))
+               return $ (if Set.null x3 then id else Heap.insert (Unsplittable x3)) $
                    Heap.insert x1 $ Heap.insert x2 xs
 
-sizeMap :: Ord a => Int -> (Map StringL (Set a)) -> (SizeMap a)
-sizeMap i m = case Map.findMax m of
+sizeMap :: (Ord a, Splittable s) => Int -> (Map (StringL s) (Set a)) -> Maybe (SizeMap s a)
+sizeMap i m = if Map.null m then Nothing else Just $ case Map.findMax m of
         (StringL _ c,_) -> if c >= i then Splittable m
                  else Unsplittable (Set.unions (Map.elems m))
 
-mkList :: Ord a => WordAssoc a -> [[a]]
+-- findMax fails on empty maps
+-- maxView might not return a Just value
+-- known offenders
+   -- ["","","",""] (empty strings have no words to key off of)
+
+mkList :: (Ord a, Splittable s) => WordAssoc s a -> [[a]]
 mkList = Prelude.map (Set.toList . toSet) . Heap.toList
diff --git a/smartGroup.cabal b/smartGroup.cabal
--- a/smartGroup.cabal
+++ b/smartGroup.cabal
@@ -7,7 +7,7 @@
 -- The package version. See the Haskell package versioning policy
 -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
 -- standards guiding when and how versions should be incremented.
-Version:             0.1.0
+Version:             0.2.0
 
 -- A short (one-line) description of the package.
 Synopsis:            group strings by words in common
@@ -52,7 +52,7 @@
   Exposed-modules:     SmartGroup
   
   -- Packages needed in order to build this package.
-  Build-depends:       base >= 3 && < 5, containers < 1, heap < 1.1
+  Build-depends:       base >= 3 && < 5, containers < 1, heap <= 1.1, bytestring < 1
   
   -- Modules not exported by this package.
   -- Other-modules:       
