diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,12 @@
 # Changelog for interval-algebra
 
+## 0.6.0
+
+* Generalizes the `IntervalAlgebraic` class to work on any data structure that *contains* an interval (not just intervals themselves). This is possible by modification to the `Intervallic` class, which now works in part as lens with `getInterval` and `setInterval` functions. This change allows users to define their own type which contains an interval get all the interval algebraic operation on that new type. The utility of this generalization can be seen in the `PairedInterval` module, which defines a parameterized type for interval *paired* with some other data.
+* Eliminates the `Moment` class and combined it with the `IntervalSizeable` class. Like the `IntervalAlgebraic` class, the `IntervalSizeable` class no longer depends on the `Interval` type, but its functions like `duration` now work on any `Intervallic i a` type.
+* Removes the `expand`, `expandl`, and `expandr` functions from the `IntervalSizeable` class are now just general functions. These function now work to modify the interval within any `Intervallic i a` type.  Similarly `beginerval`, `enderval`, and `extenterval` were removed from the class; however, these functions only *return* the `Interval` type.
+* Generalizes the `filter*` functions in the utilities module to operate on potentially different interval algebraic types. For example, in `filterOverlaps x [ys]`, `x` could be an `Interval a` and the `ys` could be a list of `PairedInterval b a`, so you can filter a container of one interval algebraic type with another interval algebraic type.
+
 ## 0.5.0
 
 * Adds the `compose` function to `IntervalAlgebraic` typeclass, thus now all the algebraic operations are available: complement, composition, converse, intersection, and union.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -6,12 +6,12 @@
 
 ## Design
 
-The module is built around four typeclasses designed to separate concerns of constructing, relating, and combining `Interval`s:
+The module is built around four typeclasses designed to separate concerns of constructing, relating, and combining types that contain `Interval`s:
 
-1. `Intervallic` provides an interface to the data structure of an `Interval`, defining how an `Interval a` (simply a pair `(a, a)`) is constructed.
-2. `IntervalAlgebraic` provides an interface to the `IntervalRelation`s, the workhorse of Allen's temporal logic.
-3. `IntervalCombinable` provides an interface to methods of combining multiple `Interval`s.
-4. `IntervalSizeable` and the related `Moment` provide methods for measuring and modifying the size of an interval.
+1. `Intervallic` provides an interface to the data structures which contain an `Interval`.
+2. `IntervalAlgebraic` provides an interface to the `IntervalRelation`, the workhorse of Allen's temporal logic.
+3. `IntervalCombinable` provides an interface to methods of combining two `Interval`s.
+4. `IntervalSizeable` provides methods for measuring and modifying the size of an interval.
 
 An advantage of nested typeclass design is that developers can define an `Interval` of type `a` with just the amount of structure that they need.
 
diff --git a/interval-algebra.cabal b/interval-algebra.cabal
--- a/interval-algebra.cabal
+++ b/interval-algebra.cabal
@@ -1,6 +1,6 @@
 cabal-version:  2.2
 name:           interval-algebra
-version:        0.5.0
+version:        0.6.0
 synopsis:       An implementation of Allen's interval algebra for temporal logic
 description:    Please see the README on GitHub at <https://github.com/novisci/interval-algebra>
 category:       Algebra,Time
@@ -25,6 +25,7 @@
       IntervalAlgebra
       IntervalAlgebra.IntervalUtilities
       IntervalAlgebra.Arbitrary
+      IntervalAlgebra.PairedInterval
   other-modules:
       Paths_interval_algebra
   autogen-modules: 
@@ -45,6 +46,7 @@
   other-modules:
       IntervalAlgebraSpec
       IntervalAlgebra.IntervalUtilitiesSpec
+      IntervalAlgebra.PairedIntervalSpec
       Paths_interval_algebra
   autogen-modules: 
       Paths_interval_algebra
diff --git a/src/IntervalAlgebra.hs b/src/IntervalAlgebra.hs
--- a/src/IntervalAlgebra.hs
+++ b/src/IntervalAlgebra.hs
@@ -1,9 +1,3 @@
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE AllowAmbiguousTypes #-}
-
 {-|
 Module      : Interval Algebra
 Description : Implementation of Allen's interval algebra
@@ -21,17 +15,16 @@
 = Design
 
 The module is built around four typeclasses designed to separate concerns of 
-constructing, relating, and combining @'Interval'@s: 
+constructing, relating, and combining types that contain @'Interval'@s: 
 
-1. @'Intervallic'@ provides an interface to the data structure of an @'Interval'@, 
-   defining how an @'Interval' a@ is constructed.
+1. @'Intervallic'@ provides an interface to the data structures which contain an
+   @'Interval'@.
 2. @'IntervalAlgebraic'@ provides an interface to the @'IntervalRelation's@, 
    the workhorse of Allen's temporal logic.
 3. @'IntervalCombinable'@ provides an interface to methods of combining two
    @'Interval's@.
-4. @'IntervalSizeable'@ and the related @'Moment'@ provides methods for 
-   measuring and modifying the size of an interval.
-   collections of intervals.
+4. @'IntervalSizeable'@ provides methods for measuring and modifying the size of
+    an interval.
 
 An advantage of nested typeclass design is that developers can define an 
 @'Interval'@ of type @a@ with just the amount of structure that they need.
@@ -47,25 +40,45 @@
 This module is under development and the API may change in the future.
 -}
 
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+
+-- {-# LANGUAGE MonoLocalBinds #-}
 module IntervalAlgebra(
 
     -- * Classes
       Intervallic(..)
     , IntervalAlgebraic(..)
     , IntervalCombinable(..)
-    , Moment(..)
     , IntervalSizeable(..)
 
     -- * Types
     , Interval
+    , parseInterval
+    , unsafeInterval
     , IntervalRelation(..)
     , ComparativePredicateOf
+
+    -- * Functions for creating new intervals from existing    
+    , expand
+    , expandl
+    , expandr
+    , beginerval
+    , enderval
+    , extenterval
 ) where
 
 import Prelude (Eq, Ord, Show, Read, Enum(..), Bounded(..), Ordering (LT)
                , Maybe(..), Either(..), String, Integer, Int, Bool(..), Num
                , Foldable (maximum, minimum, foldMap, foldr)
-               , map, otherwise, flip, show, fst, snd, min, max, any, negate, not, replicate
+               , map, otherwise, flip, show, fst, snd, min, max, any, negate, not
+               , replicate, id
                , (++), (==), (&&), (<), (>), (<=), ($), (+), (-), (.), (!!))
 import Data.Time as DT ( Day, addDays, diffDays, addGregorianYearsClip, calendarYear )
 import Data.Semigroup ( Semigroup((<>)) )
@@ -80,8 +93,47 @@
 -}
 newtype Interval a = Interval (a, a) deriving (Eq)
 
+-- | Safely parse a pair of @a@s to create an @'Interval' a@.
+parseInterval :: (Show a, Ord a) => a -> a -> Either String (Interval a)
+parseInterval x y
+    -- TODO: create more general framework for error handling
+    |  y < x    = Left  $ show y ++ "<" ++ show x
+    | otherwise = Right $ Interval (x, y)
+
+{- | Create a new @'Interval' a@. This function is __not__ safe as it does 
+    not enforce that \(x < y\). Use with caution. It is meant to be helper 
+    function in early prototyping of this package. This function may be 
+    deprecated in future releases.
+-}
+unsafeInterval :: a -> a -> Interval a
+unsafeInterval x y = Interval (x, y)
+
+intervalBegin :: Interval a -> a
+intervalBegin (Interval x) = fst x
+
+intervalEnd :: Interval a -> a
+intervalEnd (Interval x) = snd x
+
 {- | 
+The @'Intervallic'@ typeclass defines how to get and set the 'Interval' content
+of a data structure. It also includes functions for getting the @'begin'@ and 
+@'end'@ this data.
+-}
+class (Ord a) => Intervallic i a where
 
+    -- | Get the interval from an @i a@
+    getInterval :: i a -> Interval a
+
+    -- | Set the interval in an @i a@
+    setInterval :: i a -> Interval a -> i a
+
+    -- | Access the ends of an @i a@ .
+    begin, end :: i a -> a
+    begin = intervalBegin . getInterval
+    end   = intervalEnd . getInterval
+
+{- | 
+
 The 'IntervalRelation' type enumerates the thirteen possible ways that two 
 @'Interval' a@ objects can relate according to the interval algebra.
 
@@ -270,42 +322,17 @@
 -- | Defines a predicate of two objects of type @a@.
 type ComparativePredicateOf a = (a -> a -> Bool)
 
-{- | 
-The @'Intervallic'@ typeclass specifies how an @'Interval' a@s is constructed.
-It also includes functions for getting the @'begin'@ and @'end'@ of an @'Interval' a@.
--}
-class (Ord a, Show a) => Intervallic a where
 
-    -- | Safely parse a pair of @a@s to create an @'Interval' a@.
-    parseInterval :: a -> a -> Either String (Interval a)
-    parseInterval x y
-        -- TODO: create more general framework for error handling
-        |  y < x    = Left  $ show y ++ "<" ++ show x
-        | otherwise = Right $ Interval (x, y)
-
-    {- | Create a new @'Interval' a@. This function is __not__ safe as it does 
-       not enforce that \(x < y\). Use with caution. It is meant to be helper 
-       function in early prototyping of this package. This function may be 
-       deprecated in future releases.
-    -}
-    unsafeInterval :: a -> a -> Interval a
-    unsafeInterval x y = Interval (x, y)
-
-    -- | Access the ends of an @'Interval' a@ .
-    begin, end :: Interval a -> a
-    begin (Interval x) = fst x --  \( \text{begin}(x, y) = x \)
-    end   (Interval x) = snd x --  \( \text{end}(x, y) = y \)
-
 {- |
 The @'IntervalAlgebraic'@ typeclass specifies the functions and relational 
 operators for interval-based temporal logic. The typeclass defines the 
-relational operators for intervals, plus other useful utilities such as 
-@'disjoint'@, @'within'@, and @'unionPredicates'@.
+relational operators for types that contain an @'Interval a'@, plus other useful
+ utilities such as @'disjoint'@, @'within'@, and @'unionPredicates'@.
 -}
-class (Eq a, Intervallic a) => IntervalAlgebraic a where
+class (Eq (i a), Intervallic i a) => IntervalAlgebraic i a where
 
-    -- | Compare two intervals to determine their 'IntervalRelation'.
-    relate :: Interval a -> Interval a -> IntervalRelation a
+    -- | Compare two @i a@ to determine their 'IntervalRelation'.
+    relate :: i a -> i a -> IntervalRelation (i a)
     relate x y
         | x `before` y       = Before
         | x `after`  y       = After
@@ -322,7 +349,7 @@
         | otherwise          = Equals
 
     -- | Maps an 'IntervalRelation' to its corresponding predicate function.
-    predicate' :: IntervalRelation a -> ComparativePredicateOf (Interval a)
+    predicate' :: IntervalRelation (i a) -> ComparativePredicateOf (i a)
     predicate' r =
         case r of
             Before       -> before
@@ -341,148 +368,151 @@
 
     -- | Given a set of 'IntervalRelation's return a list of 'predicate' functions 
     --   corresponding to each relation.
-    predicates :: Set (IntervalRelation a) -> [ComparativePredicateOf (Interval a)]
+    predicates :: Set (IntervalRelation (i a)) -> [ComparativePredicateOf (i a)]
     predicates x = Prelude.map predicate' (toList x)
 
     -- | Forms a predicate function from the union of a set of 'IntervalRelation's.
-    predicate :: Set (IntervalRelation a) -> ComparativePredicateOf (Interval a)
+    predicate :: Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
     predicate = unionPredicates.predicates
 
     -- ** Algebraic operations on IntervalRelations
 
     -- | Shortcut to creating a 'Set IntervalRelation' from a list.
-    toSet :: [IntervalRelation a] -> Set (IntervalRelation a)
+    toSet :: [IntervalRelation (i a)] -> Set (IntervalRelation (i a))
     toSet = fromList
 
     -- | Compose two interval relations according to the rules of the algebra.
     --   The rules are enumerated according to <https://thomasalspaugh.org/pub/fnd/allen.html#BasicCompositionsTable this table>.
-    compose :: IntervalRelation a -> IntervalRelation a -> Set (IntervalRelation a)
+    compose :: IntervalRelation (i a)
+            -> IntervalRelation (i a)
+            -> Set (IntervalRelation (i a))
     compose x y = toSet ((composeRelationLookup !! fromEnum x) !! fromEnum y)
 
     -- | Finds the complement of a 'Set IntervalRelation'.
-    complement :: Set (IntervalRelation a) -> Set (IntervalRelation a)
+    complement :: Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
     complement = difference intervalRelations
 
-    -- | Find the intersection of two 'Set's of 'IntervalRelation'
-    intersection ::  Set (IntervalRelation a)
-                  -> Set (IntervalRelation a)
-                  -> Set (IntervalRelation a)
+    -- | Find the intersection of two 'Set's of 'IntervalRelation's.
+    intersection ::  Set (IntervalRelation (i a))
+                  -> Set (IntervalRelation (i a))
+                  -> Set (IntervalRelation (i a))
     intersection = Data.Set.intersection
 
-    -- | Find the union of two 'Set's of 'IntervalRelation'
-    union ::  Set (IntervalRelation a)
-           -> Set (IntervalRelation a)
-           -> Set (IntervalRelation a)
+    -- | Find the union of two 'Set's of 'IntervalRelation's.
+    union ::  Set (IntervalRelation (i a))
+           -> Set (IntervalRelation (i a))
+           -> Set (IntervalRelation (i a))
     union = Data.Set.union
 
     -- | Find the converse of a 'Set IntervalRelation'. 
-    converse ::   Set (IntervalRelation a)
-                  -> Set (IntervalRelation a)
+    converse ::   Set (IntervalRelation (i a))
+                  -> Set (IntervalRelation (i a))
     converse = Data.Set.map converseRelation
 
     -- ** Interval algebra predicates
 
     -- | Does x equal y?
-    equals                 :: ComparativePredicateOf (Interval a)
+    equals                 :: ComparativePredicateOf (i a)
     equals   x y  = x == y
 
     -- | Does x meet y? Is y metBy x?
-    meets, metBy           :: ComparativePredicateOf (Interval a)
+    meets, metBy           :: ComparativePredicateOf (i a)
     meets    x y  = end x == begin y
     metBy         = flip meets
 
     -- | Is x before y? Is x after y?
-    before, after          :: ComparativePredicateOf (Interval a)
+    before, after          :: ComparativePredicateOf (i a)
     before   x y  = end x < begin y
     after         = flip before
 
     -- | Does x overlap y? Is x overlapped by y?
-    overlaps, overlappedBy :: ComparativePredicateOf (Interval a)
+    overlaps, overlappedBy :: ComparativePredicateOf (i a)
     overlaps x y  = begin x < begin y && end x < end y && end x > begin y
     overlappedBy  = flip overlaps
 
     -- | Does x start y? Is x started by y?
-    starts, startedBy      :: ComparativePredicateOf (Interval a)
+    starts, startedBy      :: ComparativePredicateOf (i a)
     starts   x y  = begin x == begin y && (end x < end y)
     startedBy     = flip starts
 
     -- | Synonyms for 'starts' and 'startedBy'
-    precedes, precededBy      :: ComparativePredicateOf (Interval a)
+    precedes, precededBy      :: ComparativePredicateOf (i a)
     precedes      = starts
     precededBy    = startedBy
 
     -- | Does x finish y? Is x finished by y?
-    finishes, finishedBy   :: ComparativePredicateOf (Interval a)
+    finishes, finishedBy   :: ComparativePredicateOf (i a)
     finishes x y  = begin x > begin y && end x == end y
     finishedBy    = flip finishes
 
     -- | Is x during y? Does x contain y?
-    during, contains       :: ComparativePredicateOf (Interval a)
+    during, contains       :: ComparativePredicateOf (i a)
     during   x y  = begin x > begin y && end x < end y
     contains      = flip during
 
     -- ** Interval Algebra utilities
 
     -- | Compose a list of interval relations with _or_ to create a new
-    -- @'ComparativePredicateOf' 'Interval' a@. For example, 
+    -- @'ComparativePredicateOf' i a@. For example, 
     -- @unionPredicates [before, meets]@ creates a predicate function determining
     -- if one interval is either before or meets another interval.
-    unionPredicates       :: [ComparativePredicateOf (Interval a)] ->
-                              ComparativePredicateOf (Interval a)
+    unionPredicates       :: [ComparativePredicateOf (i a)] ->
+                              ComparativePredicateOf (i a)
     unionPredicates fs x y = any (\ f -> f x y) fs
 
     -- | Operator for composing the union of two predicates
-    (<|>) ::  ComparativePredicateOf (Interval a)
-        -> ComparativePredicateOf (Interval a)
-        -> ComparativePredicateOf (Interval a)
+    (<|>) ::  ComparativePredicateOf (i a)
+        -> ComparativePredicateOf (i a)
+        -> ComparativePredicateOf (i a)
     (<|>) f g = unionPredicates [f, g]
 
-    disjointRelations :: Set (IntervalRelation a)
+    disjointRelations :: Set (IntervalRelation (i a))
     disjointRelations = toSet [Before, After, Meets, MetBy]
 
-    withinRelations :: Set (IntervalRelation a)
+    withinRelations :: Set (IntervalRelation (i a))
     withinRelations = toSet [Starts, During, Finishes, Equals]
 
     -- | Are x and y disjoint ('before', 'after', 'meets', or 'metBy')?
-    disjoint               :: ComparativePredicateOf (Interval a)
+    disjoint               :: ComparativePredicateOf (i a)
     disjoint = predicate disjointRelations
 
     -- | Are x and y not disjoint; i.e. do they share any support?
-    notDisjoint            :: ComparativePredicateOf (Interval a)
+    notDisjoint            :: ComparativePredicateOf (i a)
     notDisjoint = predicate (complement disjointRelations)
 
     -- | A synonym for 'notDisjoint'.
-    concur                 :: ComparativePredicateOf (Interval a)
+    concur                 :: ComparativePredicateOf (i a)
     concur = notDisjoint
 
     -- | Is x entirely *within* the endpoints of y? That is, 'during', 
     --   'starts', 'finishes', or 'equals'?
-    within                 :: ComparativePredicateOf (Interval a)
+    within                 :: ComparativePredicateOf (i a)
     within = predicate withinRelations
 
     -- | Does x enclose y? That is, is y 'within' x?
-    enclose                :: ComparativePredicateOf (Interval a)
+    enclose                :: ComparativePredicateOf (i a)
     enclose = flip enclosedBy
 
     -- | Synonym for 'within'.
-    enclosedBy             :: ComparativePredicateOf (Interval a)
+    enclosedBy             :: ComparativePredicateOf (i a)
     enclosedBy = within
 
 {- |
-The 'Moment' class fixes the smallest duration of an 'Intervallic a'.
+The 'IntervalSizeable' typeclass provides functions to determine the size of an
+'Intervallic' type and to resize an 'Interval a'.
 -}
-class (Intervallic a, Num b, Ord b) => Moment a b| a -> b where
+class (Show a, Ord a, Num b, Ord b) => IntervalSizeable a b| a -> b where
+
+    -- | The smallest duration for an 'Interval a'.
     moment :: b
     moment = 1
 
-{- |
-The 'IntervalSizeable' typeclass provides functions to determine the size of
-and to resize an 'Interval a'.
--}
-class (Intervallic a, Moment a b, Num b, Ord b) => IntervalSizeable a b| a -> b where
+    -- | Gives back a 'moment' based on the input's type.
+    moment' :: Intervallic i a => i a -> b
+    moment' x = moment @a
 
-    -- | Determine the duration of an 'Interval a'.
-    duration :: Interval a -> b
+    -- | Determine the duration of an @'i a'@.
+    duration :: Intervallic i a => i a-> b
     duration x = diff (end x) (begin x)
 
     -- | Shifts an @a@. Most often, the @b@ will be the same type as @a@. 
@@ -492,37 +522,48 @@
     -- | Takes the difference between two @a@ to return a @b@.
     diff :: a -> a -> b
 
-    -- | Resize an 'Interval a' to by expanding to "left" by @l@ and to the 
-    --   "right" by @r@. In the case that @l@ or @r@ are less than a 'moment'
-    --   the respective endpoints are unchanged. 
-    expand :: b -> b -> Interval a -> Interval a
-    expand l r p = Interval (add s $ begin p, add e $ end p)
-      where s = if l < (moment @a) then 0 else negate l
-            e = if r < (moment @a) then 0 else r
+-- | Resize an 'i a' to by expanding to "left" by @l@ and to the 
+--   "right" by @r@. In the case that @l@ or @r@ are less than a 'moment'
+--   the respective endpoints are unchanged. 
+expand :: (IntervalSizeable a b, Intervallic i a) => b -> b -> i a -> i a
+expand l r p = setInterval p i
+  where s = if l < moment' p then 0 else negate l
+        e = if r < moment' p then 0 else r
+        i = Interval (add s $ begin p, add e $ end p)
 
-    -- | Expands an 'Interval a' to left by i.
-    expandl :: b -> Interval a -> Interval a
-    expandl i = expand i 0
+-- | Expands an 'i a' to left by i.
+expandl :: (IntervalSizeable a b, Intervallic i a) => b -> i a -> i a
+expandl i = expand i 0
 
-    -- | Expands an 'Interval a' to right by i.
-    expandr :: b -> Interval a -> Interval a
-    expandr = expand 0
+-- | Expands an 'i a' to right by i.
+expandr :: (IntervalSizeable a b, Intervallic i a) => b -> i a -> i a
+expandr = expand 0
 
-    -- | Safely creates an 'Interval a' using @x@ as the 'begin' and adding 
-    --   @max moment dur@ to @x@ as the 'end'.
-    beginerval :: b -> a -> Interval a
-    beginerval dur x = Interval (x, add (max (moment @a) dur) x)
+-- | Safely creates an 'Interval a' using @x@ as the 'begin' and adding 
+--   @max moment dur@ to @x@ as the 'end'.
+beginerval :: (IntervalSizeable a b) => b -> a -> Interval a
+beginerval dur x = Interval (x, y)
+    where i = Interval (x, x)
+          d = max (moment' i) dur
+          y = add d x
 
-    -- | Safely creates an 'Interval a' using @x@ as the 'end' and adding
-    --   @negate max moment dur@ to @x@ as the 'begin'.
-    enderval :: b -> a -> Interval a
-    enderval dur x = Interval (add (negate $ max (moment @a) dur) x, x)
+-- | Safely creates an 'Interval a' using @x@ as the 'end' and adding
+--   @negate max moment dur@ to @x@ as the 'begin'.
+enderval :: (IntervalSizeable a b) => b -> a -> Interval a
+enderval dur x = Interval (add (negate $ max (moment' i) dur) x, x)
+    where i = Interval (x, x)
 
+-- | Creates a new @Interval@ spanning the extent x and y.
+extenterval :: IntervalAlgebraic i a => i a -> i a -> Interval a
+extenterval x y = Interval (s, e)
+    where s = min (begin x) (begin y)
+          e = max (end x) (end y)
+
 {- |
 The @'IntervalCombinable'@ typeclass provides methods for (possibly) combining
 two @'Interval's@.
 -}
-class (IntervalAlgebraic a) => IntervalCombinable a where
+class (IntervalAlgebraic Interval a, Show a) => IntervalCombinable a where
 
     -- | Maybe form a new @'Interval'@ by the union of two @'Interval'@s that 'meets'.
     (.+.) :: Interval a -> Interval a -> Maybe (Interval a)
@@ -530,12 +571,6 @@
       | x `meets` y = Just $ Interval (begin x, end y)
       | otherwise   = Nothing
 
-    -- | Creates a new @Interval@ spanning the extent x and y
-    extenterval :: Interval a -> Interval a -> Interval a
-    extenterval x y = Interval (s, e)
-       where s = min (begin x) (begin y)
-             e = max (end x) (end y)
-
     -- | If @x@ is 'before' @y@, then form a new @Just Interval a@ from the 
     --   interval in the "gap" between @x@ and @y@ from the 'end' of @x@ to the
     --   'begin' of @y@. Otherwise, 'Nothing'.
@@ -565,15 +600,13 @@
            where b = max (begin x) (begin y)
                  e = min (end x) (end y)
 
-
-
-{-
-Instances
--}
+-- {-
+-- Instances
+-- -}
 
 -- | Imposes a total ordering on @'Interval' a@ based on first ordering the 
 --   'begin's then the 'end's.
-instance (Intervallic a) => Ord (Interval a) where
+instance (Eq (Interval a), Intervallic Interval a) => Ord (Interval a) where
     (<=) x y
       | begin x <  begin y = True
       | begin x == begin y = end x <= end y
@@ -583,29 +616,30 @@
       | begin x == begin y = end x < end y
       | otherwise = False
 
-instance (Intervallic a, Show a) => Show (Interval a) where
+instance (Intervallic Interval a, Show a) => Show (Interval a) where
    show x = "(" ++ show (begin x) ++ ", " ++ show (end x) ++ ")"
 
-instance Intervallic Int
-instance IntervalAlgebraic Int
+instance (Ord a, Show a) => Intervallic Interval a where
+    getInterval = id
+    setInterval _ x = x
+
+instance IntervalAlgebraic Interval Int
 instance IntervalCombinable Int
-instance Moment Int Int
 instance IntervalSizeable Int Int where
+    moment = 1
     add = (+)
     diff = (-)
 
-instance Intervallic Integer
-instance IntervalAlgebraic Integer
+instance IntervalAlgebraic Interval Integer
 instance IntervalCombinable Integer
-instance Moment Integer Integer
 instance IntervalSizeable Integer Integer where
+    moment = 1
     add = (+)
     diff = (-)
 
-instance Intervallic DT.Day
-instance IntervalAlgebraic DT.Day
+instance IntervalAlgebraic Interval DT.Day
 instance IntervalCombinable DT.Day
-instance Moment DT.Day Integer
 instance IntervalSizeable DT.Day Integer where
+    moment = 1
     add = addDays
     diff = diffDays
diff --git a/src/IntervalAlgebra/Arbitrary.hs b/src/IntervalAlgebra/Arbitrary.hs
--- a/src/IntervalAlgebra/Arbitrary.hs
+++ b/src/IntervalAlgebra/Arbitrary.hs
@@ -14,7 +14,7 @@
 import GHC.Base(Int, (.), liftM2 )
 import Control.Applicative((<$>))
 import GHC.Num ( Num((+), negate) )
-import IntervalAlgebra (Interval, IntervalSizeable(beginerval))
+import IntervalAlgebra (Interval, beginerval)
 import Data.Time as DT ( Day(ModifiedJulianDay), toModifiedJulianDay)
 
 instance Arbitrary (Interval Int) where
diff --git a/src/IntervalAlgebra/IntervalUtilities.hs b/src/IntervalAlgebra/IntervalUtilities.hs
--- a/src/IntervalAlgebra/IntervalUtilities.hs
+++ b/src/IntervalAlgebra/IntervalUtilities.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-|
 Module      : Interval Algebra Utilities
 Description : Functions for operating on containers of Intervals.
@@ -25,6 +26,7 @@
     , nothingIfAll
 
     -- * Filtering functions
+    , compareIntervals
     , filterBefore
     , filterMeets
     , filterOverlaps
@@ -40,7 +42,10 @@
     , filterAfter
     , filterDisjoint
     , filterNotDisjoint
+    , filterConcur
     , filterWithin
+    , filterEnclose
+    , filterEnclosedBy
 
 ) where
 
@@ -49,7 +54,8 @@
     , Semigroup((<>))
     , Functor(fmap)
     , Applicative(pure)
-    , Int, Bool)
+    , Int, Bool, Ord)
+import GHC.Show ( Show )
 import GHC.Num ()
 import Data.Tuple ( fst )
 import Data.Foldable ( Foldable(null, foldl', toList), all, any )
@@ -58,7 +64,11 @@
     ( Interval, Intervallic(..), IntervalAlgebraic(..)
     , IntervalCombinable(..), IntervalSizeable(..)
     , IntervalRelation(..)
-    , ComparativePredicateOf)
+    , ComparativePredicateOf
+    , unsafeInterval
+    , beginerval
+    , enderval
+    )
 import Data.Maybe (mapMaybe, catMaybes, fromMaybe, Maybe(..))
 import Data.List ( (++), map, head, init, last, tail )
 import Witherable ( Filterable(filter) )
@@ -158,12 +168,12 @@
       [Interval a]
 gaps' x = catMaybes (foldlAccume (><) x)
 
--- | Returns the 'duration' of each 'Interval' in the 'Functor' @f@.
+-- | Returns the 'duration' of each 'Intervallic i a' in the 'Functor' @f@.
 --
 -- >>> durations [intInt 1 10, intInt 2 12, intInt 5 6]
 -- [9,10,1]
-durations :: (Functor f, IntervalSizeable a b)=>
-       f (Interval a)
+durations :: (Functor f, Intervallic i a, IntervalSizeable a b)=>
+       f (i a)
     -> f b
 durations = fmap duration
 
@@ -174,7 +184,7 @@
 --
 -- >>> clip (intInt 0 3) (intInt 4 6)
 -- Nothing
-clip :: (IntervalAlgebraic a, IntervalSizeable a b)=>
+clip :: (IntervalAlgebraic Interval a, IntervalSizeable a b)=>
        Interval a
     -> Interval a
     -> Maybe (Interval a)
@@ -193,21 +203,21 @@
 --
 -- >>> relations [intInt 0 1, intInt 1 2] 
 -- [Meets]
-relations :: (IntervalAlgebraic a, Foldable f)=>
-       f (Interval a)
-    -> [IntervalRelation a]
+relations :: (IntervalAlgebraic i a, Foldable f)=>
+       f (i a)
+    -> [IntervalRelation (i a)]
 relations = relations'
 
 -- | A generic form of 'relations' which can output any 'Applicative' and 
 --   'Monoid' structure. 
 -- >>> (relations' [intInt 0 1, intInt 1 2]) :: [IntervalRelation Int]
 -- [Meets]
-relations' :: ( IntervalAlgebraic a
+relations' :: ( IntervalAlgebraic i a
               , Foldable f
               , Applicative m
-              , Monoid (m (IntervalRelation a)) )=>
-        f (Interval a)
-     -> m (IntervalRelation a)
+              , Monoid (m (IntervalRelation (i a))) )=>
+        f (i a)
+     -> m (IntervalRelation (i a))
 relations' = foldlAccume relate
 
 -- | Applies 'gaps' to all the non-disjoint intervals in @x@ that are *not* disjoint
@@ -224,7 +234,7 @@
                , IntervalSizeable a b
                , IntervalCombinable a
                , Filterable f
-               , IntervalAlgebraic a)=>
+               , IntervalAlgebraic Interval a)=>
      Interval a     -- ^ i
   -> f (Interval a) -- ^ x
   -> Maybe (f (Interval a))
@@ -238,153 +248,221 @@
 
 -- | Given a predicate combinator, a predicate, and list of intervals, returns 
 --   the input unchanged if the predicate combinator is @True@. Otherwise, returns
---   an empty list. See 'emptyIfAny' and 'emptyIfNone' for examples.
-nothingIf :: (Monoid (f (Interval a)), Filterable f, IntervalAlgebraic a)=>
-     ((Interval a -> Bool) -> f (Interval a) -> Bool) -- ^ e.g. 'any' or 'all'
-  -> (Interval a -> Bool) -- ^ predicate to apply to each element of input list
-  -> f (Interval a)
-  -> Maybe (f (Interval a))
+--   an empty list. See 'nothingIfAny' and 'nothingIfNone' for examples.
+nothingIf :: (Monoid (f (i a)), Filterable f, IntervalAlgebraic i a)=>
+     ((i a -> Bool) -> f (i a) -> Bool) -- ^ e.g. 'any' or 'all'
+  -> (i a -> Bool) -- ^ predicate to apply to each element of input list
+  -> f (i a)
+  -> Maybe (f (i a))
 nothingIf quantifier predicate x = if quantifier predicate x then Nothing else Just x
 
--- | Returns the empty monoid structure if *none* of the element of input satisfy
+-- | Returns the 'Nothing' if *none* of the element of input satisfy
 --   the predicate condition.
 -- 
--- For example, the following returns the empty list because none of the intervals
+-- For example, the following returns 'Nothing' because none of the intervals
 -- in the input list 'starts' (3, 5).
 --
 -- >>> nothingIfNone (starts (intInt 3 5)) [intInt 3 4, intInt 5 6]
+-- Nothing
 --
--- In the following, (3, 5) 'starts' (3, 6), so the input is returned.
+-- In the following, (3, 5) 'starts' (3, 6), so 'Just' the input is returned.
 --
 -- >>> nothingIfNone (starts (intInt 3 5)) [intInt 3 6, intInt 5 6]
+-- Just [(3, 6),(5, 6)]
 --
-nothingIfNone :: (Monoid (f (Interval a)), Foldable f, Filterable f, IntervalAlgebraic a)=>
-    (Interval a -> Bool) -- ^ predicate to apply to each element of input list
-  -> f (Interval a)
-  -> Maybe (f (Interval a))
+nothingIfNone :: (Monoid (f (i a)), Foldable f, Filterable f, IntervalAlgebraic i a)=>
+    (i a -> Bool) -- ^ predicate to apply to each element of input list
+  -> f (i a)
+  -> Maybe (f (i a))
 nothingIfNone = nothingIf (\f x -> (not.any f) x)
 
--- | Returns the empty monoid structure if *any* of the element of input satisfy
---   the predicate condition
-nothingIfAny :: (Monoid (f (Interval a)), Foldable f, Filterable f, IntervalAlgebraic a)=>
-    (Interval a -> Bool) -- ^ predicate to apply to each element of input list
-  -> f (Interval a)
-  -> Maybe (f (Interval a))
+-- | Returns 'Nothing' if *any* of the element of input satisfy the predicate condition.
+nothingIfAny :: (Monoid (f (i a)), Foldable f, Filterable f, IntervalAlgebraic i a)=>
+    (i a -> Bool) -- ^ predicate to apply to each element of input list
+  -> f (i a)
+  -> Maybe (f (i a))
 nothingIfAny = nothingIf any
 
--- | Returns the empty monoid structure if *all* of the element of input satisfy
---   the predicate condition
-nothingIfAll :: (Monoid (f (Interval a)), Foldable f, Filterable f, IntervalAlgebraic a)=>
-    (Interval a -> Bool) -- ^ predicate to apply to each element of input list
-  -> f (Interval a)
-  -> Maybe (f (Interval a))
+-- | Returns 'Nothing' if *all* of the element of input satisfy the predicate condition
+nothingIfAll :: (Monoid (f (i a)), Foldable f, Filterable f, IntervalAlgebraic i a)=>
+    (i a -> Bool) -- ^ predicate to apply to each element of input list
+  -> f (i a)
+  -> Maybe (f (i a))
 nothingIfAll = nothingIf all
 
-
 {- | 
 Filter functions provides means for filtering 'Filterable' containers of 
-@'Interval'@s based on @'IntervalAlgebraic'@ relations.
+@'Intervallic i a'@s based on @'IntervalAlgebraic'@ relations.
 -}
 
--- |Creates a function for filtering a 'Witherable.Filterable' of @Interval a@s based on a predicate
-filterMaker :: (Filterable f, IntervalAlgebraic a) =>
-                 ComparativePredicateOf (Interval a)
-                -> Interval a
-                -> (f (Interval a) -> f (Interval a))
-filterMaker f p = Witherable.filter (`f` p)
+-- | Lifts a predicate to be able to compare two different 'IntervalAlgebraic' 
+--   structure by comparing the intervals contain within each. 
+compareIntervals :: (IntervalAlgebraic i0 a, IntervalAlgebraic i1 a) =>
+   ComparativePredicateOf (Interval a) 
+    -> i0 a
+    -> i1 a
+    -> Bool
+compareIntervals pf x y = pf (getInterval x) (getInterval y)
 
--- | Filter a 'Witherable.Filterable' of @Interval a@s to those that 'overlaps' the @Interval a@
---   in the first argument.
-filterOverlaps :: (Filterable f, IntervalAlgebraic a) => 
-                  Interval a -> f (Interval a) -> f (Interval a)
+-- | Creates a function for filtering a 'Witherable.Filterable' of @i1 a@s 
+--   by comparing the @Interval a@s that of an @i0 a@. 
+filterMaker :: (Filterable f
+                , IntervalAlgebraic Interval a
+                , IntervalAlgebraic i0 a
+                , IntervalAlgebraic i1 a) =>
+        ComparativePredicateOf (Interval a)
+      -> i0 a
+      -> (f (i1 a) -> f (i1 a))
+filterMaker f p = Witherable.filter (compareIntervals f p)
+
+-- | Filter by 'overlaps'.
+filterOverlaps :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterOverlaps = filterMaker overlaps
 
--- | Filter a 'Witherable.Filterable' of @Interval a@s to those 'overlappedBy' the @Interval a@
---   in the first argument.
-filterOverlappedBy :: (Filterable f, IntervalAlgebraic a) => 
-                      Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'overlappedBy'.
+filterOverlappedBy :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterOverlappedBy = filterMaker overlappedBy
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'before' the @Interval a@
---   in the first argument.
-filterBefore :: (Filterable f, IntervalAlgebraic a) => 
-                Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'before'.
+filterBefore :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterBefore = filterMaker before
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'after' the @Interval a@
---   in the first argument.
-filterAfter :: (Filterable f, IntervalAlgebraic a) => 
-               Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'after'.
+filterAfter :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a) 
 filterAfter = filterMaker after
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'starts' the @Interval a@
---   in the first argument.
-filterStarts :: (Filterable f, IntervalAlgebraic a) => 
-               Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'starts'.
+filterStarts :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterStarts = filterMaker starts 
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'startedBy' the @Interval a@
---   in the first argument.
-filterStartedBy :: (Filterable f, IntervalAlgebraic a) => 
-               Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'startedBy'.
+filterStartedBy :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterStartedBy = filterMaker startedBy 
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'finishes' the @Interval a@
---   in the first argument.
-filterFinishes :: (Filterable f, IntervalAlgebraic a) => 
-               Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'finishes'.
+filterFinishes :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterFinishes = filterMaker finishes
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'finishedBy' the @Interval a@
---   in the first argument.
-filterFinishedBy :: (Filterable f, IntervalAlgebraic a) => 
-               Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by'finishedBy'.
+filterFinishedBy :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterFinishedBy = filterMaker finishedBy 
 
--- | Filter a 'Witherable.Filterable' of Interval as to those that 'meets' the @Interval a@
---   in the first argument.
-filterMeets :: (Filterable f, IntervalAlgebraic a) => 
-               Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'meets'.
+filterMeets :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterMeets = filterMaker meets
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'metBy' the @Interval a@
---   in the first argument.
-filterMetBy :: (Filterable f, IntervalAlgebraic a) => 
-               Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'metBy'.
+filterMetBy :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterMetBy = filterMaker metBy
 
--- | Filter a 'Witherable.Filterable' of Interval as to those 'during' the @Interval a@
---   in the first argument.
-filterDuring :: (Filterable f, IntervalAlgebraic a) => 
-                Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'during'.
+filterDuring :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterDuring = filterMaker during
 
--- | Filter a 'Witherable.Filterable' of Interval as to those that 'contains'
---   the @Interval a@ in the first argument.
-filterContains :: (Filterable f, IntervalAlgebraic a) => 
-                  Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'contains'.
+filterContains :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterContains = filterMaker contains
 
--- | Filter a 'Witherable.Filterable' of Interval as to those that 'equals'
---   the @Interval a@ in the first argument.
-filterEquals :: (Filterable f, IntervalAlgebraic a) => 
-                  Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'equals'.
+filterEquals :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterEquals = filterMaker equals
 
--- | Filter a 'Witherable.Filterable' of Interval as to those that are 'disjoint'
---   from the @Interval a@ in the first argument.
-filterDisjoint :: (Filterable f, IntervalAlgebraic a) => 
-                  Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'disjoint'.
+filterDisjoint :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterDisjoint = filterMaker disjoint
 
--- | Filter a 'Witherable.Filterable' of Interval as to those that are 'notDisjoint'
---   from the @Interval a@ in the first argument.
-filterNotDisjoint :: (Filterable f, IntervalAlgebraic a) => 
-                     Interval a -> f (Interval a) -> f (Interval a)
+-- | Filter by 'notDisjoint'.
+filterNotDisjoint :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
 filterNotDisjoint = filterMaker notDisjoint
 
--- | Filter a 'Witherable.Filterable' of Interval as to those that are 'within'
---   the @Interval a@ in the first argument.
-filterWithin :: (Filterable f, IntervalAlgebraic a) => 
-                Interval a -> f (Interval a) -> f (Interval a)
-filterWithin = filterMaker disjoint
+-- | Filter by 'concur'.
+filterConcur ::  (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
+filterConcur = filterMaker concur
+
+-- | Filter by 'within'.
+filterWithin :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
+filterWithin = filterMaker within
+
+-- | Filter by 'enclose'.
+filterEnclose :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
+filterEnclose = filterMaker enclose
+
+-- | Filter by 'enclosedBy'.
+filterEnclosedBy :: (Filterable f
+                  , IntervalAlgebraic Interval a
+                  , IntervalAlgebraic i0 a
+                  , IntervalAlgebraic i1 a) => 
+                  i0 a -> f (i1 a) -> f (i1 a)
+filterEnclosedBy = filterMaker enclosedBy
diff --git a/src/IntervalAlgebra/PairedInterval.hs b/src/IntervalAlgebra/PairedInterval.hs
new file mode 100644
--- /dev/null
+++ b/src/IntervalAlgebra/PairedInterval.hs
@@ -0,0 +1,67 @@
+{-|
+Module      : Paired interval 
+Description : Extends the Interval Algebra to an interval paired with some data.
+Copyright   : (c) NoviSci, Inc 2020
+License     : BSD3
+Maintainer  : bsaul@novisci.com
+Stability   : experimental
+-}
+
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleContexts #-}
+
+module IntervalAlgebra.PairedInterval (
+      PairedInterval
+    , mkPairedInterval
+    , pairData
+    , intervals
+    , makePairPredicate
+) where
+
+import IntervalAlgebra
+    ( Interval
+    , Intervallic(..)
+    , IntervalAlgebraic(..)
+    , ComparativePredicateOf )
+import IntervalAlgebra.IntervalUtilities(compareIntervals, filterOverlaps)
+import Witherable ( Filterable(filter) )
+
+-- | An @Interval a@ paired with some other data of type @b@.
+newtype PairedInterval b a = PairedInterval (Interval a, b)
+    deriving (Eq, Show)
+
+instance (Ord a) => Intervallic (PairedInterval b) a where
+    getInterval (PairedInterval x)        = fst x
+    setInterval (PairedInterval (x, y)) i = PairedInterval (i, y)
+
+-- | Defines A total ordering on 'PairedInterval b a' based on the 'Interval a'
+--   part.
+instance (Eq a, Eq b, Ord a, Show a) => Ord (PairedInterval b a) where
+  (<=) x y = getInterval x <= getInterval y
+  (<) x y  = getInterval x <  getInterval y
+
+instance (Eq b) => IntervalAlgebraic (PairedInterval b) Int 
+
+-- | Make a paired interval. 
+mkPairedInterval :: b -> Interval a -> PairedInterval b a
+mkPairedInterval d i = PairedInterval (i, d)
+
+-- | Gets the data (i.e. non-interval) part of a @PairedInterval@.
+pairData :: PairedInterval b a -> b
+pairData (PairedInterval (_, y)) = y
+
+-- | Gets the intervals from a list of paired intervals.
+intervals :: Ord a => [PairedInterval b a] -> [Interval a]
+intervals = map getInterval
+
+-- | Takes a predicate of intervals and a predicate on the data part of a 
+--   paired interval to create a single predicate such that both input
+--   predicates should hold.
+makePairPredicate :: (IntervalAlgebraic (PairedInterval b) a) =>
+       ComparativePredicateOf (Interval a)
+    -> ComparativePredicateOf b
+    -> ComparativePredicateOf (PairedInterval b a)
+makePairPredicate intervalPredicate dataPredicate x y =
+         compareIntervals intervalPredicate x y &&
+         dataPredicate (pairData x) (pairData y)
diff --git a/test/IntervalAlgebra/IntervalUtilitiesSpec.hs b/test/IntervalAlgebra/IntervalUtilitiesSpec.hs
--- a/test/IntervalAlgebra/IntervalUtilitiesSpec.hs
+++ b/test/IntervalAlgebra/IntervalUtilitiesSpec.hs
@@ -1,10 +1,14 @@
 {-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE FlexibleContexts #-}
 module IntervalAlgebra.IntervalUtilitiesSpec (spec) where
 
-import IntervalAlgebra ( Interval, Intervallic(unsafeInterval)
-                        , IntervalCombinable(..)
-                        , IntervalAlgebraic(..)
-                        , IntervalRelation (..) )
+import IntervalAlgebra ( 
+    Interval
+   , Intervallic(..)
+   , unsafeInterval
+   , IntervalCombinable(..)
+   , IntervalAlgebraic(..)
+   , IntervalRelation (..) )
 import IntervalAlgebra.Arbitrary ()
 import IntervalAlgebra.IntervalUtilities
 import Test.Hspec.QuickCheck ( modifyMaxSuccess )
@@ -27,13 +31,13 @@
 gapInt :: Interval Int
 gapInt = unsafeInterval (10 :: Int) (15 :: Int)
 
-prop_combineIntervals1:: (IntervalAlgebraic a, IntervalCombinable a)=>
+prop_combineIntervals1:: (IntervalAlgebraic Interval a, IntervalCombinable a)=>
      [Interval a]
    -> Property
 prop_combineIntervals1 x = relations ci === replicate (length ci - 1) Before
       where ci = combineIntervals (sort x)
 
-prop_gaps1:: (IntervalAlgebraic a, IntervalCombinable a)=>
+prop_gaps1:: (IntervalAlgebraic Interval a, IntervalCombinable a)=>
      [Interval a]
    -> Property
 prop_gaps1 x = relations gs === replicate (length gs - 1) Before
@@ -122,3 +126,12 @@
             nothingIfNone (starts (intInt 3 5)) [intInt 3 6, intInt 5 6]
                `shouldBe` Just [ intInt 3 6, intInt 5 6]
          it "more emptyif tests" pending
+
+   describe "filtration tests" $
+      do 
+         it "disjoint filter should filter out noncontainment" $
+            filterDisjoint containmentInt [noncontainmentInt, anotherInt] 
+               `shouldBe` [anotherInt]
+         it "notDisjoint filter should keep noncontainment" $
+            filterNotDisjoint containmentInt [noncontainmentInt, anotherInt] 
+               `shouldBe` [noncontainmentInt]
diff --git a/test/IntervalAlgebra/PairedIntervalSpec.hs b/test/IntervalAlgebra/PairedIntervalSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/IntervalAlgebra/PairedIntervalSpec.hs
@@ -0,0 +1,25 @@
+module IntervalAlgebra.PairedIntervalSpec (spec) where
+
+import Test.Hspec ( it, describe, Spec, shouldBe )
+import IntervalAlgebra.PairedInterval
+import IntervalAlgebra
+
+type TestPair = PairedInterval String Int
+
+mkTestPr :: String -> Int -> Int -> TestPair
+mkTestPr x i j = mkPairedInterval x (unsafeInterval i j)
+
+t1 :: TestPair
+t1 = mkTestPr "hi" 0 5
+t2 :: TestPair
+t2 = mkTestPr "bye" 6 10
+
+spec :: Spec
+spec = do
+    describe "tests on paired intervals" $
+        do 
+            it "t1 is before t2" $
+                (t1 `before` t2) `shouldBe` True
+            it "duration of t1 is 5" $
+                duration t1 `shouldBe` 5
+                
diff --git a/test/IntervalAlgebraSpec.hs b/test/IntervalAlgebraSpec.hs
--- a/test/IntervalAlgebraSpec.hs
+++ b/test/IntervalAlgebraSpec.hs
@@ -1,8 +1,8 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE TypeApplications #-}
-
 -- {-# LANGUAGE AllowAmbiguousTypes #-}
 -- {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleContexts #-}
 module IntervalAlgebraSpec (spec) where
 
 import Test.Hspec ( hspec, describe, it, Spec, shouldBe )
@@ -28,11 +28,11 @@
   | otherwise = x
 
 -- | A function for creating intervals when you think you know what you're doing.
-safeInterval :: (Intervallic a) => a -> a -> Interval a
+safeInterval :: Ord a => a -> a -> Interval a
 safeInterval x y = unsafeInterval (min x y) (max x y)
 
 -- | Create a 'Maybe Interval a' from two @a@s.
-safeInterval'' :: (Intervallic a) => a -> a -> Maybe (Interval a)
+safeInterval'' :: Ord a => a -> a -> Maybe (Interval a)
 safeInterval'' x y
     | y <= x    = Nothing
     | otherwise = Just $ safeInterval x y
@@ -80,7 +80,7 @@
    \forall i,j,k,l s.t. (i:j & i:k & l:j) \implies l:k
  \] 
 -}
-prop_IAaxiomM1 :: (IntervalAlgebraic a) => M1set a -> Property
+prop_IAaxiomM1 :: (IntervalAlgebraic Interval a) => M1set a -> Property
 prop_IAaxiomM1 x =
   (i `meets` j && i `meets` k && l `meets` j) ==> (l `meets` k)
   where i = m11 x
@@ -144,7 +144,7 @@
  \] 
 -}
 
-prop_IAaxiomM2 :: (IntervalAlgebraic a) => M2set a -> Property
+prop_IAaxiomM2 :: (Show a, IntervalAlgebraic Interval a) => M2set a -> Property
 prop_IAaxiomM2 x =
   (i `meets` j && k `meets` l) ==>
     (i `meets` l)  `xor`
@@ -174,7 +174,7 @@
  \] 
 -}
 
-prop_IAaxiomML1 :: (IntervalAlgebraic a) => Interval a -> Property
+prop_IAaxiomML1 :: (IntervalAlgebraic Interval a) => Interval a -> Property
 prop_IAaxiomML1 x = not (x `meets` x) === True
 
 prop_IAaxiomML1_Int :: Interval Int -> Property
@@ -194,7 +194,7 @@
 \] 
 -}
 
-prop_IAaxiomML2 :: (IntervalAlgebraic a)=> M2set a -> Property
+prop_IAaxiomML2 :: (IntervalAlgebraic Interval a)=> M2set a -> Property
 prop_IAaxiomML2 x =
   (i `meets` j) ==> not (j `meets` i)
   where i = m21 x
@@ -217,7 +217,7 @@
 \] 
 -}
 
-prop_IAaxiomM3 :: (IntervalAlgebraic a, IntervalSizeable a b)=>
+prop_IAaxiomM3 :: (IntervalAlgebraic Interval a, IntervalSizeable a b)=>
       b -> Interval a -> Property
 prop_IAaxiomM3 b i =
    (j `meets` i && i `meets` k) === True
@@ -241,7 +241,7 @@
 \] 
 -}
 
-prop_IAaxiomM4 :: (IntervalAlgebraic a, IntervalSizeable a b)=>
+prop_IAaxiomM4 :: (IntervalAlgebraic Interval a, IntervalSizeable a b)=>
      b -> M2set a -> Property
 prop_IAaxiomM4 moment x =
    ((m `meets` i && i `meets` j && j `meets` n) &&
@@ -295,7 +295,7 @@
         ps = end (expandr (makePos b) x) -- creating l by shifting and expanding i
 
 
-prop_IAaxiomM5 :: (IntervalAlgebraic a) => M5set a -> Property
+prop_IAaxiomM5 :: (Show a, IntervalAlgebraic Interval a) => M5set a -> Property
 prop_IAaxiomM5 x =
    ((i `meets` j && j `meets` l) &&
     (i `meets` k && k `meets` l))  === (j == k)
@@ -342,7 +342,7 @@
 * Interval Relation property testing 
 -}
 
-class (IntervalAlgebraic a, IntervalCombinable a)=> IntervalRelationProperties a where
+class (IntervalAlgebraic Interval a, IntervalCombinable a)=> IntervalRelationProperties a where
 
     prop_IAbefore :: Interval a -> Interval a -> Property
     prop_IAbefore i j =
@@ -384,7 +384,7 @@
 
 instance IntervalRelationProperties Int
 
-allIArelations:: IntervalAlgebraic a => [ComparativePredicateOf (Interval a)]
+allIArelations:: IntervalAlgebraic Interval a => [ComparativePredicateOf (Interval a)]
 allIArelations =   [  IA.equals
                     , IA.meets
                     , IA.metBy
@@ -399,14 +399,14 @@
                     , IA.during
                     , IA.contains ]
 
-prop_expandl_end ::(IntervalAlgebraic a, IntervalSizeable a b)=>
+prop_expandl_end ::(IntervalAlgebraic Interval a, IntervalSizeable a b)=>
        b
     -> Interval a
     -> Property
 prop_expandl_end d i = end (expandl d i) === end i
 
 
-prop_expandr_begin ::(IntervalAlgebraic a, IntervalSizeable a b)=>
+prop_expandr_begin ::(IntervalAlgebraic Interval a, IntervalSizeable a b)=>
        b
     -> Interval a
     -> Property
@@ -414,7 +414,7 @@
 
 -- | The relation between x and z should be an element of the set of the
 --   composed relations between x y and between y z.
-prop_compose :: IntervalAlgebraic a =>
+prop_compose :: IntervalAlgebraic Interval a =>
        Interval a
     -> Interval a
     -> Interval a
