diff --git a/Data/GPS.hs b/Data/GPS.hs
--- a/Data/GPS.hs
+++ b/Data/GPS.hs
@@ -1,22 +1,10 @@
-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, EmptyDataDecls #-}
--- |Author: Thomas DuBuisson
--- Copyright: Thomas DuBuisson
--- License: BSD3
---
--- A basic GPS library with calculations for distance and speed along
+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, EmptyDataDecls, BangPatterns #-}
+-- |A basic GPS library with calculations for distance and speed along
 -- with helper functions for filtering/smoothing trails.  All distances
 -- are in meters and time is in seconds.  Speed is thus meters/second
---
--- The current intent of this library is to
---   1) Provide a standard type class interface for coordinates
---   2) Include fleshed out support for relevant libraries, a task
---      too often neglected in modern Hackage packages.
---
---  Integration includes KML support via the xml package, pretty printing,
---  anb binary.
 
 module Data.GPS
-	( -- * Types and Classes
+	( -- * Types
 	  Distance
 	, Heading
 	, Speed
@@ -28,17 +16,26 @@
 	, east
 	, west
 	, radiusOfEarth
-	-- * Helper Functions
+	-- * Coordinate Functions
 	, heading
-	, restLocations
-	, closestDistance
-	, getRadianPair
+	, distance
+	, speed
 	, addVector
+	, getRadianPair
+	, getDMSPair
 	, divideArea
+        -- * Trail Functions
+	, totalDistance
+	, restLocations
+	, closestDistance
+	, filterByMaxSpeed
 	, convexHull
+	-- * Other helpers
+	, readGPX
 	, module Data.Geo.GPX
 	) where
 
+import Data.Function (on)
 import Data.Ord (comparing)
 import Data.List (sort, mapAccumL, minimumBy, maximumBy, sortBy)
 import Data.Geo.GPX hiding (none, cmt)
@@ -49,6 +46,7 @@
 import Data.Time
 import Data.Maybe (listToMaybe)
 import Data.Fixed
+import Control.Monad
 
 -- |Distances are expressed in meters
 type Distance = Double
@@ -76,6 +74,10 @@
   (lat1, lon1) = getRadianPairD a
   (lat2, lon2) = getRadianPairD b
 
+-- | Find the total distance traveled
+totalDistance :: (Lat a, Lon a) => [a] -> Distance
+totalDistance as = sum $ zipWith distance as (drop 1 as)
+
 -- | Direction two points aim toward (0 = North, pi/2 = West, pi = South, 3pi/2 = East)
 heading         :: (Lat a, Lon a) => a -> a -> Heading	-- ^ 0 = North, pi/2 = West...
 heading a b =
@@ -89,13 +91,21 @@
 getVector :: (Lat a, Lon a) => a -> a -> Vector
 getVector a b = (distance a b, heading a b)
 
--- | Speed in meters per second
+-- | Speed in meters per second, only if a 'Time' was recorded for each waypoint.
 speed :: (Lat loc, Lon loc, Time loc) => loc -> loc -> Maybe Speed
 speed a b = 
 	case (getUTCTime b, getUTCTime a) of
 		(Just x, Just y) -> Just $ realToFrac (diffUTCTime x y) / (distance a b)
 		_ -> Nothing
 
+-- |Filter out all points that result in a speed greater than a given value
+-- (the second point is dropped)
+filterByMaxSpeed :: (Lat loc, Lon loc, Time loc) => Speed -> Trail loc -> Trail loc
+filterByMaxSpeed mx xs =
+	let ss = zipWith speed xs (drop 1 xs)
+	    fs = filter ((< Just mx) . fst) (zip ss $ drop 1 xs)
+	in take 1 xs ++ map snd fs
+
 data TempTrail a = T (Trail a) a
 
 -- |radius of the earth in meters
@@ -141,6 +151,9 @@
 getRadianPairD :: (Lat c, Lon c) => c -> (Double,Double)
 getRadianPairD = (\(a,b) -> (realToFrac a, realToFrac b)) . getRadianPair
 
+getDMSPair :: (Lat c, Lon c) => c -> (LatitudeType, LongitudeType)
+getDMSPair c = (lat c, lon c)
+
 -- |Provides a lat/lon pair of doubles in radians
 getRadianPair :: (Lat p, Lon p) => p -> (LatitudeType, LongitudeType)
 getRadianPair p = (t, g)
@@ -174,14 +187,14 @@
   where
   go [] = []
   go (a:as) =
-	let (lst, close, far) = takeWhileLast ((<= d) . distance a) as
-	in case lst of
-		Just x -> case (getUTCTime a, getUTCTime x) of
-				(Just a', Just x') ->
-					let d = diffUTCTime a' x'
-			  		in if d >= s then close : go far else go as
+	case takeWhileLast ((<=) d . distance a) as of
+		(Just l, close, far) ->
+			case (getUTCTime a, getUTCTime l) of
+				(Just t1, Just t2) ->
+					let diff = diffUTCTime t2 t1
+					in if diff >= s then (a:close) : go far else go as
 				_ -> go as
-		Nothing -> go as
+		_ -> go as
 
 takeWhileLast :: (a -> Bool) -> [a] -> (Maybe a, [a], [a])
 takeWhileLast p [] = (Nothing, [], [])
@@ -189,10 +202,10 @@
 	| not (p x) = (Nothing, [], x:xs)
 	| otherwise = go x xs
   where
-  go a [] = (Just a, [a], [])
-  go a (b:bs)
+  go !a [] = (Just a, [], [])
+  go !a (b:bs)
 	| p b = let (c,d,f) = go b bs in (c, a:d, f)
-	| otherwise = (Just a, [a], b:bs)
+	| otherwise = (Just a, [], b:bs)
 
 -- |Returns the closest distance between two trails (or Nothing if a trail is empty)
 -- O( (n * m) * log (n * m) )
@@ -212,6 +225,11 @@
 	    columnOne = takeWhile ( (<= west) . heading se) . iterate (addVector (vDist, south)) $ nw
 	    buildRow  = takeWhile ((>= north) . heading se) . iterate (addVector (hDist, east))
 	in map buildRow columnOne
+
+-- |Reads a GPX file (using the GPX library) by simply concatenating all the
+-- tracks, segments, and points ('trkpts', 'trksegs', 'trks') into a single 'Trail'.
+readGPX :: FilePath -> IO (Trail WptType)
+readGPX = liftM (concatMap trkpts . concatMap trksegs . concatMap trks) . readGpxFile
 
 -- | Uses Grahams scan to compute the convex hull of the given points.
 -- This operation requires sorting of the points, so don't try it unless
diff --git a/gps.cabal b/gps.cabal
--- a/gps.cabal
+++ b/gps.cabal
@@ -1,5 +1,5 @@
 name:		gps
-version:	0.5.4
+version:	0.6
 license:	BSD3
 license-file:	LICENSE
 author:		Thomas DuBuisson <thomas.dubuisson@gmail.com>
@@ -13,12 +13,9 @@
 tested-with:	GHC == 6.10.3
 extra-source-files: 
 
-Flag small_base
-  Description: Choose the split-up base package.
-
 Library
-  Build-Depends: base >= 4 && < 6, bytestring >= 0.9 && < 1.0,
-                   pretty >= 1.0 && < 1.1 , prettyclass >= 1.0 && < 1.1,
+  Build-Depends: base >= 3 && < 6,
+                   pretty >= 1.0 , prettyclass >= 1.0,
                    time >= 1.1 && < 1.3, GPX == 0.4.*, hxt >= 8.5, xsd == 0.3.*
   hs-source-dirs:
   exposed-modules: Data.GPS
