diff --git a/Data/List/PointedList.hs b/Data/List/PointedList.hs
--- a/Data/List/PointedList.hs
+++ b/Data/List/PointedList.hs
@@ -2,13 +2,13 @@
 --   an index position in the list (the 'focus').
 module Data.List.PointedList where
 
-import Prelude hiding (foldl, foldr)
+import Prelude hiding (foldl, foldr, elem)
 
 import Control.Applicative
 import Control.Monad
 import Data.Binary
-import Data.Foldable
-import Data.List hiding (foldl, foldr)
+import Data.Foldable hiding (find)
+import Data.List hiding (length, foldl, foldr, find, elem)
 import Data.Maybe
 import Data.Traversable
 
@@ -144,6 +144,26 @@
 -- > contextMap atStart (fromJust $ fromList [1..5])
 contextMap :: (PointedList a -> b) -> PointedList a -> PointedList b
 contextMap f z = fmap f $ positions z
+
+-- | Move the focus to the specified index. 
+move :: Int -> PointedList a -> Maybe (PointedList a)
+move n pl@(PointedList a _ _) | n <     0 || n >= Data.List.PointedList.length pl
+                                                       = Nothing 
+                              | Prelude.length a == n  = Just pl
+                              | Prelude.length a >= n  = move n (tryPrevious pl)
+                              | otherwise              = move n (tryNext pl)
+
+-- | Move the focus to the specified element, if it is present.
+find :: Eq a => a -> PointedList a -> Maybe (PointedList a)
+find x pl@(PointedList a b c)
+  | x == b     = Just pl
+  | x `elem` a = find x (tryPrevious pl)
+  | x `elem` c = find x (tryNext pl)
+  | otherwise  = Nothing
+
+-- | Determine the index of the focus.
+index :: PointedList a -> Int
+index (PointedList a _ _) = Prelude.length a
 
 --------------------------------------------------------
 -- DERIVES GENERATED CODE
diff --git a/Data/List/PointedList/Circular.hs b/Data/List/PointedList/Circular.hs
new file mode 100644
--- /dev/null
+++ b/Data/List/PointedList/Circular.hs
@@ -0,0 +1,65 @@
+module Data.List.PointedList.Circular
+  ( -- Re-export many of the regular PointedList features
+  module Data.List.PointedList
+
+  -- And, of course, export the alternatives here
+  , next
+  , previous
+  , delete
+  , deleteLeft
+  , deleteRight
+  ) where
+
+import Data.List.PointedList
+  ( PointedList(..)
+  , singleton
+  , fromList
+  , fromListEnd
+  , focus
+  , insert
+  , insertLeft
+  , insertRight
+  , length
+  , positions
+  , contextMap
+  , move
+  , find
+  , index
+  )
+import qualified Data.List.PointedList as PL
+
+next :: PointedList a -> PointedList a
+next pl@(PointedList [] b []) = pl
+next    (PointedList a  b []) = let (x:xs) = reverse a in
+                                  PointedList [] x (xs ++ [b])
+next pl = PL.tryNext pl 
+
+previous :: PointedList a -> PointedList a
+previous pl@(PointedList [] b []) = pl
+previous    (PointedList [] b c ) = let (x:xs) = reverse c in
+                                      PointedList (xs ++ [b]) x []
+previous pl = PL.tryPrevious pl
+
+-- | An alias of 'deleteRight'.
+delete :: PointedList a -> Maybe (PointedList a)
+delete = deleteRight
+
+-- | Possibly delete the element at the focus, then move the element on the
+--   left to the focus. If no element is on the left, focus on the element to
+--   the right. If the deletion will cause the list to be empty, return
+--   @Nothing@.
+deleteLeft :: PointedList a -> Maybe (PointedList a)
+deleteLeft (PointedList []     _ []) = Nothing
+deleteLeft (PointedList (l:ls) _ rs) = Just $ PointedList ls l rs
+deleteLeft (PointedList []     _ rs) = let (x:xs) = reverse rs in
+                                         Just $ PointedList xs x []
+
+-- | Possibly delete the element at the focus, then move the element on the
+--   right to the focus. If no element is on the right, focus on the element to
+--   the left. If the deletion will cause the list to be empty, return
+--   @Nothing@.
+deleteRight :: PointedList a -> Maybe (PointedList a)
+deleteRight (PointedList [] _ []    ) = Nothing
+deleteRight (PointedList ls _ (r:rs)) = Just $ PointedList ls r rs
+deleteRight (PointedList ls _ []    ) = let (x:xs) = reverse ls in
+                                            Just $ PointedList [] x xs
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,5 +1,15 @@
 #!/usr/bin/env runhaskell
+import Distribution.PackageDescription
 import Distribution.Simple
+import Distribution.Simple.LocalBuildInfo
 
+-- Import the local test suite
+import Tests.PL (test)
+
+runTest :: Args -> Bool -> PackageDescription -> LocalBuildInfo -> IO ()
+runTest _ _ _descr _buildInfo = test
+
 main :: IO ()
-main = defaultMain
+main = defaultMainWithHooks $ simpleUserHooks {
+    runTests = runTest
+  }
diff --git a/pointedlist.cabal b/pointedlist.cabal
--- a/pointedlist.cabal
+++ b/pointedlist.cabal
@@ -1,16 +1,20 @@
 Name:          pointedlist
-Version:       0.1
+Version:       0.2
 Synopsis:      A zipper-like comonad which works as a list, tracking a position.
 Category:      Data
 Description:
     A PointedList tracks the position in a non-empty list which works similarly
     to a zipper. A current item is always required, and therefore the list may
     never be empty.
+
+    A circular PointedList wraps around to the other end when progressing past
+    the actual edge.
 License:       BSD3
 License-file:  LICENSE
 Author:        Jeff Wheeler
 Maintainer:    jeffwheeler@gmail.com
-Build-type:    Simple
+Build-type:    Custom
 Build-depends: base>=4
 Build-depends: binary
 Exposed-modules: Data.List.PointedList
+                 Data.List.PointedList.Circular
