diff --git a/Data/GPS/Trail.hs b/Data/GPS/Trail.hs
--- a/Data/GPS/Trail.hs
+++ b/Data/GPS/Trail.hs
@@ -3,6 +3,8 @@
        ( -- * Types         
          AvgMethod(..)
        , Selected(..)
+       , PointGrouping
+       , TransformGrouping
          -- * Utility Functions
        , isSelected
        , isNotSelected
@@ -36,8 +38,8 @@
        , (/\), (\/)
          -- ** Composite Operations (Higher Level)
        , smoothRests
-       , smoothSegments
---       , smoothPath
+       , smoothSome
+       , smoothMore
         -- * Misc
        , bezierPoint
          ) where
@@ -121,20 +123,21 @@
   getSpeedsV = V.fromList . getSpeeds
   getSpeeds zs = concatMap maybeToList $ zipWith speed zs (drop 1 zs)
 
-type TrailTransformation c = [Selected (Trail c)] -> Trail c
-
 -- | A PointGrouping is a function that selects segments of a trail.
 -- 
 -- Grouping point _does not_ result in deleted points. It is always true that:
 --
---     forall g : PointGrouping c -->
+--     forall g :: PointGrouping c -->
 --     concatMap unSelect (g ts) == ts
 --
 -- The purpose of grouping is usually for later processing.  Any desire to drop
 -- points that didn't meet a particular grouping criteria can be filled with
--- a composition with 'filter' (or directly via 'filterPoints'.
+-- a composition with 'filter' (or directly via 'filterPoints').
 type PointGrouping c = Trail c -> [Selected (Trail c)]
 
+-- | Given a selection of coordinates, transform the selected
+-- coordinates in some way (while leaving the non-selected
+-- coordinates unaffected).
 type TransformGrouping c = [Selected (Trail c)] -> [Selected (Trail c)]
 
 -- | When grouping points, lists of points are either marked as 'Select' or 'NotSelect'.
@@ -208,8 +211,9 @@
 spansTime n ps =
   let times  = mkTimePair ps
       chunk [] = []
-      chunk (x:xs) =
-        let (good,rest) = span ((<= addUTCTime n (snd x)) . snd) xs in good : chunk rest
+      chunk xs@(x:_) =
+        let (good,rest) = span ((<= addUTCTime n (snd x)) . snd) xs 
+        in if null good then [xs] else good : chunk rest
   in map (Select . map fst) $ chunk times
 
 -- | intersects the given groupings
@@ -334,6 +338,7 @@
 -- coordinates are available and all equal (Ex: all points are 5
 -- seconds apart), the results will be poor if this is not the case!
 bezierCurveAt :: (Lat a, Lon a, Time a) => [UTCTime] -> Trail a -> Trail a
+bezierCurveAt _ [] = []
 bezierCurveAt selectedTimes xs = 
   let timesDef = mkTimePair xs
       end = last timesDef
@@ -342,10 +347,10 @@
       times = if null selectedTimes then map snd timesDef else selectedTimes
       diffTimes = [diffUTCTime t (snd top) / totalTime | t <- times]
       queryTimes = map realToFrac diffTimes
-  in if any (\x -> x < 0 || x > 1) queryTimes
-	then error "bezierCurveAt has a out-of-bound time!"
+  in if totalTime <= 0 || any (\x -> x < 0 || x > 1) queryTimes
+	then xs -- error "bezierCurveAt has a out-of-bound time!"
         else
-         if null timesDef || totalTime == 0 || any (\x -> x < 0 || x > 1) queryTimes
+         if null timesDef || any (\x -> x < 0 || x > 1) queryTimes
          then xs
          else let curvePoints = (map (bezierPoint xs) queryTimes)
                   newTimes = [addUTCTime t (snd top) | t <- diffTimes]
@@ -437,18 +442,20 @@
 smoothRests :: (Lat a, Lon a, Time a) => Trail a -> Trail a
 smoothRests = bezierCurve . refineGrouping (everyNPoints 8) . restLocations 30 60
 
-smoothSegments :: (Lat a, Lon a, Time a) => Trail a -> Trail a
-smoothSegments ps = bezierCurve . everyNPoints 7 $ ps
-{-
-  let op xs =
-        let xs' = bezierCurve . everyNPoints 7 $ xs
-            (h,t) = splitAt 3 xs'
-            xs''  = bezierCurve . everyNPoints 7 $ xs'
-        in h ++ xs''
-  in iterate op ps !! 10
--}
-smoothPath :: (Lat a, Lon a, Time a) => Trail a -> Trail a
-smoothPath ps = undefined
+smoothSome :: (Lat a, Lon a, Time a) => Trail a -> Trail a
+smoothSome = gSmoothSome 7
+
+gSmoothSome n = bezierCurve . everyNPoints n
+
+gSmoothMore n k ps =
+  let ps' = gSmoothSome n ps
+      (h,t) = splitAt k ps'
+  in h ++ gSmoothSome n t
+
+smoothMore :: (Lat a, Lon a, Time a) => Trail a -> Trail a
+smoothMore
+  = gSmoothMore 7 3 . gSmoothMore 3 1 . gSmoothMore 5 2
+  . gSmoothMore 3 1 . gSmoothMore 5 2 . gSmoothMore 7 3
   
 slidingWindow :: Int -> Int -> ([a] -> [a]) -> [a] -> [a]
 slidingWindow width step f trail = go trail
diff --git a/gps.cabal b/gps.cabal
--- a/gps.cabal
+++ b/gps.cabal
@@ -1,5 +1,5 @@
 name:		gps
-version:	0.8.2
+version:	0.8.3
 license:	BSD3
 license-file:	LICENSE
 author:		Thomas DuBuisson <thomas.dubuisson@gmail.com>
