diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -2,18 +2,18 @@
 
 regex is a regular expression toolkit for regex-base with:
 
-  * text-replacement operations with named captures;
+  * a text-replacement toolkit with type-safe text-replacement templates;
   * special datatypes for matches and captures;
   * compile-time checking of RE syntax;
   * a unified means of controlling case-sensitivity and multi-line options;
   * high-level AWK-like tools for building text processing apps;
   * the option of using match operators with reduced polymorphism on the
-    text and/or result types;
+    text and result types;
   * regular expression macros including:
       + a number of useful RE macros;
       + a test bench for testing and documenting new macro environments;
   * built-in support for the TDFA and PCRE backends;
-  * comprehensive documentation and copious examples.
+  * comprehensive documentation, tutorials and copious examples.
 
 
 See the [About page](http://about.regex.uk) for details.
@@ -70,8 +70,12 @@
 
 &nbsp;&nbsp;&nbsp;&nbsp;&#x2612;&nbsp;&nbsp;2017-03-29  v0.11.0.0 [Simplify the API](https://github.com/iconnect/regex/milestone/14)
 
-&nbsp;&nbsp;&nbsp;&nbsp;&#x2610;&nbsp;&nbsp;2017-03-31  v1.0.0.0  [First stable release](https://github.com/iconnect/regex/milestone/3)
+&nbsp;&nbsp;&nbsp;&nbsp;&#x2612;&nbsp;&nbsp;2017-03-30  v0.11.1.0 [Fix the Haddocks](https://github.com/iconnect/regex/milestone/15)
 
+&nbsp;&nbsp;&nbsp;&nbsp;&#x2612;&nbsp;&nbsp;2017-03-31  v0.12.0.0 [Move IsRegex into Text.RE](https://github.com/iconnect/regex/milestone/16)
+
+&nbsp;&nbsp;&nbsp;&nbsp;&#x2610;&nbsp;&nbsp;2017-04-03  v1.0.0.0  [First stable release](https://github.com/iconnect/regex/milestone/3)
+
 &nbsp;&nbsp;&nbsp;&nbsp;&#x2610;&nbsp;&nbsp;2017-08-31  v2.0.0.0  [Fast text replacement with benchmarks](https://github.com/iconnect/regex/milestone/4)
 
 
@@ -109,9 +113,9 @@
 
 If you have any feedback or suggestion then please drop us a line.
 
-&nbsp;&nbsp;&nbsp;&nbsp;`t` [&#64;hregex](https://twitter.com/hregex)\n
-&nbsp;&nbsp;&nbsp;&nbsp;`e` maintainers@regex.uk\n
-&nbsp;&nbsp;&nbsp;&nbsp;`w` http://issues.regex.uk
+  * `t` [&#64;hregex](https://twitter.com/hregex)\n
+  * `e` maintainers@regex.uk\n
+  * `w` http://issues.regex.uk
 
 The [Contact page](http://contact.regex.uk) has more details.
 
diff --git a/Text/RE.hs b/Text/RE.hs
--- a/Text/RE.hs
+++ b/Text/RE.hs
@@ -31,8 +31,17 @@
   , matchSource
   , matched
   , matchedText
+
+  -- * IsRegex
+  -- $isregex
+  , IsRegex(..)
+  , searchReplaceAll
+  , searchReplaceFirst
+  , module Text.RE.TDFA
   ) where
 
+import           Text.RE.TDFA()
+import           Text.RE.ZeInternals.Types.IsRegex
 import           Text.RE.ZeInternals.Types.Match
 import           Text.RE.ZeInternals.Types.Matches
 
@@ -84,3 +93,10 @@
 -- * "Text.RE.TestBench" for building up, testing and doumenting;
 --   macro environments  for use in REs;
 -- * "Text.RE.Tools"     for an AWK-like text-processing toolkit.
+
+-- $isregex
+-- Class @IsRegex re t@ provides methods for matching the @t@ type for
+-- the @re@ back end as well as compiling REs from @t@ to @re@ and
+-- getting the source @t@ back again. The 'Replace' superclass of
+-- @IsRegex@ contains a useful toolkit for converting between @t@ and
+-- 'String' abd @Text@.
diff --git a/Text/RE/IsRegex.lhs b/Text/RE/IsRegex.lhs
deleted file mode 100644
--- a/Text/RE/IsRegex.lhs
+++ /dev/null
@@ -1,60 +0,0 @@
-\begin{code}
-{-# LANGUAGE RecordWildCards            #-}
-{-# LANGUAGE MultiParamTypeClasses      #-}
-{-# LANGUAGE AllowAmbiguousTypes        #-}
-{-# LANGUAGE CPP                        #-}
-#if __GLASGOW_HASKELL__ >= 800
-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
-#endif
-
-module Text.RE.IsRegex
-  ( IsRegex(..)
-  , SearchReplace(..)
-  , searchReplaceAll
-  , searchReplaceFirst
-  ) where
-
-import           Text.RE.ZeInternals.EscapeREString
-import           Text.RE.ZeInternals.Types.Match
-import           Text.RE.ZeInternals.Types.Matches
-import           Text.RE.REOptions
-import           Text.RE.Replace
-import           Text.RE.ZeInternals.Types.SearchReplace
-\end{code}
-
-\begin{code}
--- | the 'IsRegex' class allows polymorhic tools to be written that
--- will work with a variety of regex back ends and text types
-class Replace s => IsRegex re s where
-  -- | finding the first match
-  matchOnce             :: re -> s -> Match s
-  -- | finding all matches
-  matchMany             :: re -> s -> Matches s
-  -- | compiling an RE, failing if the RE is not well formed
-  makeRegex             :: (Functor m,Monad m) => s -> m re
-  -- | comiling an RE, specifying the 'SimpleREOptions'
-  makeRegexWith         :: (Functor m,Monad m) => SimpleREOptions -> s -> m re
-  -- | compiling a 'SearchReplace' template from the RE text and the template Text, failing if they are not well formed
-  makeSearchReplace     :: (Functor m,Monad m,IsRegex re s) => s -> s -> m (SearchReplace re s)
-  -- | compiling a 'SearchReplace' template specifing the 'SimpleREOptions' for the RE
-  makeSearchReplaceWith :: (Functor m,Monad m,IsRegex re s) => SimpleREOptions -> s -> s -> m (SearchReplace re s)
-  -- | incorporate an escaped string into a compiled RE with the default options
-  makeEscaped           :: (Functor m,Monad m) => (s->s) -> s -> m re
-  -- | incorporate an escaped string into a compiled RE with the specified 'SimpleREOptions'
-  makeEscapedWith       :: (Functor m,Monad m) => SimpleREOptions -> (s->s) -> s -> m re
-  -- | extract the text of the RE from the RE
-  regexSource           :: re -> s
-
-  makeRegex           = makeRegexWith         minBound
-  makeSearchReplace   = makeSearchReplaceWith minBound
-  makeEscaped         = makeEscapedWith       minBound
-  makeEscapedWith o f = makeRegexWith o . f . packR . escapeREString . unpackR
-
--- | searching and replacing the first occurrence
-searchReplaceAll :: IsRegex re s => SearchReplace re s -> s -> s
-searchReplaceAll SearchReplace{..} = replaceAll getTemplate . matchMany getSearch
-
--- | searching and replaceing all occurrences
-searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s
-searchReplaceFirst SearchReplace{..} = replace    getTemplate . matchOnce getSearch
-\end{code}
diff --git a/Text/RE/Replace.hs b/Text/RE/Replace.hs
--- a/Text/RE/Replace.hs
+++ b/Text/RE/Replace.hs
@@ -18,6 +18,45 @@
   , Replace(..)
   , ReplaceMethods(..)
   , replaceMethods
+  -- * Matches
+  , Matches(..)
+  , anyMatches
+  , countMatches
+  , matches
+  , mainCaptures
+  -- * Match
+  , Match(..)
+  , noMatch
+  , emptyMatchArray
+  , matched
+  , matchedText
+  , matchCapture
+  , matchCaptures
+  , (!$$)
+  , captureText
+  , (!$$?)
+  , captureTextMaybe
+  , (!$)
+  , capture
+  , (!$?)
+  , captureMaybe
+  , convertMatchText
+  -- * Capture
+  , Capture(..)
+  , hasCaptured
+  , capturePrefix
+  , captureSuffix
+  -- * CaptureID
+  , CaptureID(..)
+  , CaptureNames
+  , noCaptureNames
+  , CaptureName(..)
+  , CaptureOrdinal(..)
+  , findCaptureID
   ) where
 
 import           Text.RE.ZeInternals.Replace
+import           Text.RE.ZeInternals.Types.Capture
+import           Text.RE.ZeInternals.Types.CaptureID
+import           Text.RE.ZeInternals.Types.Match
+import           Text.RE.ZeInternals.Types.Matches
diff --git a/Text/RE/Summa.hs b/Text/RE/Summa.hs
--- a/Text/RE/Summa.hs
+++ b/Text/RE/Summa.hs
@@ -1,12 +1,12 @@
 module Text.RE.Summa
   ( -- $collection
-    module Text.RE.IsRegex
+    module Text.RE.REOptions
   , module Text.RE.Replace
   , module Text.RE.TestBench
   , module Text.RE.Tools
   ) where
 
-import Text.RE.IsRegex
+import Text.RE.REOptions
 import Text.RE.Replace
 import Text.RE.TestBench
 import Text.RE.Tools
diff --git a/Text/RE/TDFA.hs b/Text/RE/TDFA.hs
--- a/Text/RE/TDFA.hs
+++ b/Text/RE/TDFA.hs
@@ -39,14 +39,19 @@
   -- $options
   , SimpleREOptions(..)
   -- * Compiling and Escaping REs
+  , SearchReplace(..)
   , compileRegex
   , compileRegexWith
+  , compileSearchReplace
+  , compileSearchReplaceWith
   , escape
   , escapeWith
   , escapeREString
   -- * The Classic rexex-base Match Operators
   , (=~)
   , (=~~)
+  -- * IsRegex
+  , IsRegex(..)
   -- * The Quasi Quoters and Minor Functions
   -- $re
   , module Text.RE.ZeInternals.TDFA
@@ -62,20 +67,21 @@
   , module Text.RE.TDFA.Text.Lazy
   ) where
 
-import qualified Text.Regex.Base                          as B
-import           Text.RE
-import           Text.RE.ZeInternals.AddCaptureNames
-import           Text.RE.ZeInternals.SearchReplace.TDFA
-import           Text.RE.ZeInternals.TDFA
-import qualified Text.Regex.TDFA                          as TDFA
+import           Text.RE.REOptions
 import           Text.RE.TDFA.ByteString()
 import           Text.RE.TDFA.ByteString.Lazy()
 import           Text.RE.TDFA.Sequence()
 import           Text.RE.TDFA.String()
 import           Text.RE.TDFA.Text()
 import           Text.RE.TDFA.Text.Lazy()
-import           Text.RE.IsRegex
-import           Text.RE.REOptions
+import           Text.RE.ZeInternals.AddCaptureNames
+import           Text.RE.ZeInternals.SearchReplace.TDFA
+import           Text.RE.ZeInternals.TDFA
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.RE.ZeInternals.Types.Match
+import           Text.RE.ZeInternals.Types.Matches
+import qualified Text.Regex.Base                          as B
+import qualified Text.Regex.TDFA                          as TDFA
 
 
 -- | find all the matches in the argument text; e.g., to count the number
diff --git a/Text/RE/TDFA/ByteString.hs b/Text/RE/TDFA/ByteString.hs
--- a/Text/RE/TDFA/ByteString.hs
+++ b/Text/RE/TDFA/ByteString.hs
@@ -39,14 +39,19 @@
   -- $options
   , SimpleREOptions(..)
   -- * Compiling and Escaping REs
+  , SearchReplace(..)
   , compileRegex
   , compileRegexWith
+  , compileSearchReplace
+  , compileSearchReplaceWith
   , escape
   , escapeWith
   , escapeREString
   -- * The Classic rexex-base Match Operators
   , (=~)
   , (=~~)
+  -- * IsRegex
+  , IsRegex(..)
   -- * The Quasi Quoters and Minor Functions
   -- $re
   , module Text.RE.ZeInternals.TDFA
@@ -57,14 +62,13 @@
 import           Prelude.Compat
 import qualified Data.ByteString               as B
 import           Data.Typeable
-import           Text.Regex.Base
-import           Text.RE
-import           Text.RE.ZeInternals.AddCaptureNames
-import           Text.RE.ZeInternals.SearchReplace.TDFA.ByteString
-import           Text.RE.IsRegex
 import           Text.RE.REOptions
 import           Text.RE.Replace
+import           Text.RE.ZeInternals.AddCaptureNames
+import           Text.RE.ZeInternals.SearchReplace.TDFA.ByteString
 import           Text.RE.ZeInternals.TDFA
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.Regex.Base
 import qualified Text.Regex.TDFA               as TDFA
 
 
@@ -101,7 +105,7 @@
 -- e.g., to prefix the first string of four hex digits in the imput text,
 -- if any, with @0x@:
 --
---  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])
+--  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@
 --
 (?=~/) :: B.ByteString -> SearchReplace RE B.ByteString -> B.ByteString
 (?=~/) = flip searchReplaceFirst
diff --git a/Text/RE/TDFA/ByteString/Lazy.hs b/Text/RE/TDFA/ByteString/Lazy.hs
--- a/Text/RE/TDFA/ByteString/Lazy.hs
+++ b/Text/RE/TDFA/ByteString/Lazy.hs
@@ -39,14 +39,19 @@
   -- $options
   , SimpleREOptions(..)
   -- * Compiling and Escaping REs
+  , SearchReplace(..)
   , compileRegex
   , compileRegexWith
+  , compileSearchReplace
+  , compileSearchReplaceWith
   , escape
   , escapeWith
   , escapeREString
   -- * The Classic rexex-base Match Operators
   , (=~)
   , (=~~)
+  -- * IsRegex
+  , IsRegex(..)
   -- * The Quasi Quoters and Minor Functions
   -- $re
   , module Text.RE.ZeInternals.TDFA
@@ -57,14 +62,13 @@
 import           Prelude.Compat
 import qualified Data.ByteString.Lazy.Char8    as LBS
 import           Data.Typeable
-import           Text.Regex.Base
-import           Text.RE
-import           Text.RE.ZeInternals.AddCaptureNames
-import           Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy
-import           Text.RE.IsRegex
 import           Text.RE.REOptions
 import           Text.RE.Replace
+import           Text.RE.ZeInternals.AddCaptureNames
+import           Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy
 import           Text.RE.ZeInternals.TDFA
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.Regex.Base
 import qualified Text.Regex.TDFA               as TDFA
 
 
@@ -101,7 +105,7 @@
 -- e.g., to prefix the first string of four hex digits in the imput text,
 -- if any, with @0x@:
 --
---  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])
+--  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@
 --
 (?=~/) :: LBS.ByteString -> SearchReplace RE LBS.ByteString -> LBS.ByteString
 (?=~/) = flip searchReplaceFirst
diff --git a/Text/RE/TDFA/Sequence.hs b/Text/RE/TDFA/Sequence.hs
--- a/Text/RE/TDFA/Sequence.hs
+++ b/Text/RE/TDFA/Sequence.hs
@@ -39,14 +39,19 @@
   -- $options
   , SimpleREOptions(..)
   -- * Compiling and Escaping REs
+  , SearchReplace(..)
   , compileRegex
   , compileRegexWith
+  , compileSearchReplace
+  , compileSearchReplaceWith
   , escape
   , escapeWith
   , escapeREString
   -- * The Classic rexex-base Match Operators
   , (=~)
   , (=~~)
+  -- * IsRegex
+  , IsRegex(..)
   -- * The Quasi Quoters and Minor Functions
   -- $re
   , module Text.RE.ZeInternals.TDFA
@@ -57,14 +62,13 @@
 import           Prelude.Compat
 import qualified Data.Sequence                 as S
 import           Data.Typeable
-import           Text.Regex.Base
-import           Text.RE
-import           Text.RE.ZeInternals.AddCaptureNames
-import           Text.RE.ZeInternals.SearchReplace.TDFA.Sequence
-import           Text.RE.IsRegex
 import           Text.RE.REOptions
 import           Text.RE.Replace
+import           Text.RE.ZeInternals.AddCaptureNames
+import           Text.RE.ZeInternals.SearchReplace.TDFA.Sequence
 import           Text.RE.ZeInternals.TDFA
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.Regex.Base
 import qualified Text.Regex.TDFA               as TDFA
 
 
@@ -101,7 +105,7 @@
 -- e.g., to prefix the first string of four hex digits in the imput text,
 -- if any, with @0x@:
 --
---  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])
+--  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@
 --
 (?=~/) :: (S.Seq Char) -> SearchReplace RE (S.Seq Char) -> (S.Seq Char)
 (?=~/) = flip searchReplaceFirst
diff --git a/Text/RE/TDFA/String.hs b/Text/RE/TDFA/String.hs
--- a/Text/RE/TDFA/String.hs
+++ b/Text/RE/TDFA/String.hs
@@ -39,14 +39,19 @@
   -- $options
   , SimpleREOptions(..)
   -- * Compiling and Escaping REs
+  , SearchReplace(..)
   , compileRegex
   , compileRegexWith
+  , compileSearchReplace
+  , compileSearchReplaceWith
   , escape
   , escapeWith
   , escapeREString
   -- * The Classic rexex-base Match Operators
   , (=~)
   , (=~~)
+  -- * IsRegex
+  , IsRegex(..)
   -- * The Quasi Quoters and Minor Functions
   -- $re
   , module Text.RE.ZeInternals.TDFA
@@ -57,14 +62,13 @@
 import           Prelude.Compat
 
 import           Data.Typeable
-import           Text.Regex.Base
-import           Text.RE
-import           Text.RE.ZeInternals.AddCaptureNames
-import           Text.RE.ZeInternals.SearchReplace.TDFA.String
-import           Text.RE.IsRegex
 import           Text.RE.REOptions
 import           Text.RE.Replace
+import           Text.RE.ZeInternals.AddCaptureNames
+import           Text.RE.ZeInternals.SearchReplace.TDFA.String
 import           Text.RE.ZeInternals.TDFA
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.Regex.Base
 import qualified Text.Regex.TDFA               as TDFA
 
 
@@ -101,7 +105,7 @@
 -- e.g., to prefix the first string of four hex digits in the imput text,
 -- if any, with @0x@:
 --
---  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])
+--  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@
 --
 (?=~/) :: String -> SearchReplace RE String -> String
 (?=~/) = flip searchReplaceFirst
diff --git a/Text/RE/TDFA/Text.hs b/Text/RE/TDFA/Text.hs
--- a/Text/RE/TDFA/Text.hs
+++ b/Text/RE/TDFA/Text.hs
@@ -39,14 +39,19 @@
   -- $options
   , SimpleREOptions(..)
   -- * Compiling and Escaping REs
+  , SearchReplace(..)
   , compileRegex
   , compileRegexWith
+  , compileSearchReplace
+  , compileSearchReplaceWith
   , escape
   , escapeWith
   , escapeREString
   -- * The Classic rexex-base Match Operators
   , (=~)
   , (=~~)
+  -- * IsRegex
+  , IsRegex(..)
   -- * The Quasi Quoters and Minor Functions
   -- $re
   , module Text.RE.ZeInternals.TDFA
@@ -57,14 +62,13 @@
 import           Prelude.Compat
 import qualified Data.Text                     as T
 import           Data.Typeable
-import           Text.Regex.Base
-import           Text.RE
-import           Text.RE.ZeInternals.AddCaptureNames
-import           Text.RE.ZeInternals.SearchReplace.TDFA.Text
-import           Text.RE.IsRegex
 import           Text.RE.REOptions
 import           Text.RE.Replace
+import           Text.RE.ZeInternals.AddCaptureNames
+import           Text.RE.ZeInternals.SearchReplace.TDFA.Text
 import           Text.RE.ZeInternals.TDFA
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.Regex.Base
 import qualified Text.Regex.TDFA               as TDFA
 
 
@@ -101,7 +105,7 @@
 -- e.g., to prefix the first string of four hex digits in the imput text,
 -- if any, with @0x@:
 --
---  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])
+--  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@
 --
 (?=~/) :: T.Text -> SearchReplace RE T.Text -> T.Text
 (?=~/) = flip searchReplaceFirst
diff --git a/Text/RE/TDFA/Text/Lazy.hs b/Text/RE/TDFA/Text/Lazy.hs
--- a/Text/RE/TDFA/Text/Lazy.hs
+++ b/Text/RE/TDFA/Text/Lazy.hs
@@ -39,14 +39,19 @@
   -- $options
   , SimpleREOptions(..)
   -- * Compiling and Escaping REs
+  , SearchReplace(..)
   , compileRegex
   , compileRegexWith
+  , compileSearchReplace
+  , compileSearchReplaceWith
   , escape
   , escapeWith
   , escapeREString
   -- * The Classic rexex-base Match Operators
   , (=~)
   , (=~~)
+  -- * IsRegex
+  , IsRegex(..)
   -- * The Quasi Quoters and Minor Functions
   -- $re
   , module Text.RE.ZeInternals.TDFA
@@ -57,14 +62,13 @@
 import           Prelude.Compat
 import qualified Data.Text.Lazy                as TL
 import           Data.Typeable
-import           Text.Regex.Base
-import           Text.RE
-import           Text.RE.ZeInternals.AddCaptureNames
-import           Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy
-import           Text.RE.IsRegex
 import           Text.RE.REOptions
 import           Text.RE.Replace
+import           Text.RE.ZeInternals.AddCaptureNames
+import           Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy
 import           Text.RE.ZeInternals.TDFA
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.Regex.Base
 import qualified Text.Regex.TDFA               as TDFA
 
 
@@ -101,7 +105,7 @@
 -- e.g., to prefix the first string of four hex digits in the imput text,
 -- if any, with @0x@:
 --
---  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])
+--  @(?=~\/ [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|])@
 --
 (?=~/) :: TL.Text -> SearchReplace RE TL.Text -> TL.Text
 (?=~/) = flip searchReplaceFirst
diff --git a/Text/RE/TestBench.hs b/Text/RE/TestBench.hs
--- a/Text/RE/TestBench.hs
+++ b/Text/RE/TestBench.hs
@@ -8,6 +8,10 @@
   , MacroDescriptor(..)
   , RegexSource(..)
   , WithCaptures(..)
+  , RegexType
+  , isTDFA
+  , isPCRE
+  , presentRegexType
   -- ** Constructing a MacrosEnv
   , mkMacros
   -- ** Formatting Macros
@@ -39,7 +43,6 @@
   , Severity(..)
   , parseSeverity
   , severityKeywords
---  , module Text.RE.ZeInternals.TestBench
   ) where
 
 import           Data.Array
diff --git a/Text/RE/Tools/Edit.lhs b/Text/RE/Tools/Edit.lhs
--- a/Text/RE/Tools/Edit.lhs
+++ b/Text/RE/Tools/Edit.lhs
@@ -29,10 +29,9 @@
 import           Data.Maybe
 import           Prelude.Compat
 import           Text.RE
-import           Text.RE.ZeInternals.Types.Capture
-import           Text.RE.IsRegex
-import           Text.RE.ZeInternals.Types.LineNo
 import           Text.RE.Replace
+import           Text.RE.ZeInternals.Types.IsRegex
+import           Text.RE.ZeInternals.Types.LineNo
 
 
 -- | an 'Edits' script will, for each line in the file, either perform
diff --git a/Text/RE/Tools/Grep.lhs b/Text/RE/Tools/Grep.lhs
--- a/Text/RE/Tools/Grep.lhs
+++ b/Text/RE/Tools/Grep.lhs
@@ -28,7 +28,6 @@
 import           Prelude.Compat
 import           Text.Printf
 import           Text.RE
-import           Text.RE.IsRegex
 import           Text.RE.ZeInternals.Types.LineNo
 
 
diff --git a/Text/RE/Tools/Lex.hs b/Text/RE/Tools/Lex.hs
new file mode 100644
--- /dev/null
+++ b/Text/RE/Tools/Lex.hs
@@ -0,0 +1,11 @@
+module Text.RE.Tools.Lex
+  ( alex
+  , alex'
+  -- * IsRegex
+  , IsRegex(..)
+  -- * Text.RE
+  , module Text.RE
+  ) where
+
+import           Text.RE
+import           Text.RE.ZeInternals.Lex
diff --git a/Text/RE/Tools/Lex.lhs b/Text/RE/Tools/Lex.lhs
deleted file mode 100644
--- a/Text/RE/Tools/Lex.lhs
+++ /dev/null
@@ -1,52 +0,0 @@
-\begin{code}
-{-# LANGUAGE NoImplicitPrelude          #-}
-
-module Text.RE.Tools.Lex
-  ( alex
-  , alex'
-  -- * IsRegex
-  , IsRegex(..)
-  -- * Text.RE
-  , module Text.RE
-  ) where
-
-import           Prelude.Compat
-import           Text.RE
-import           Text.RE.ZeInternals.Types.Capture
-import           Text.RE.IsRegex
-import           Text.RE.ZeInternals.Types.Match
-import           Text.RE.Replace
-
-
--- | a simple regex-based scanner interpretter for prototyping
--- scanners
-alex :: IsRegex re s => [(re,Match s->Maybe t)] -> t -> s -> [t]
-alex = alex' matchOnce
-
--- | a higher order version of 'alex' parameterised over the @matchOnce@
--- function
-alex' :: Replace s
-      => (re->s->Match s)
-      -> [(re,Match s->Maybe t)]
-      -> t
-      -> s
-      -> [t]
-alex' mo al t_err = loop
-  where
-    loop s = case lengthR s == 0 of
-      True  -> []
-      False -> choose al s
-
-    choose []           _ = [t_err]
-    choose ((re,f):al') s = case mb_p of
-        Just (s',t) -> t : loop s'
-        _           -> choose al' s
-      where
-        mb_p = do
-          cap <- matchCapture mtch
-          case captureOffset cap == 0 of
-            True  -> (,) (captureSuffix cap) <$> f mtch
-            False -> Nothing
-
-        mtch = mo re s
-\end{code}
diff --git a/Text/RE/Tools/Sed.lhs b/Text/RE/Tools/Sed.lhs
--- a/Text/RE/Tools/Sed.lhs
+++ b/Text/RE/Tools/Sed.lhs
@@ -31,9 +31,8 @@
 import qualified Data.ByteString.Lazy.Char8               as LBS
 import           Prelude.Compat
 import           Text.RE
-import           Text.RE.Tools.Edit
-import           Text.RE.IsRegex
 import           Text.RE.Replace
+import           Text.RE.Tools.Edit
 
 
 -- | read a file, apply an 'Edits' script to each line it and
diff --git a/Text/RE/ZeInternals/AddCaptureNames.hs b/Text/RE/ZeInternals/AddCaptureNames.hs
--- a/Text/RE/ZeInternals/AddCaptureNames.hs
+++ b/Text/RE/ZeInternals/AddCaptureNames.hs
@@ -14,9 +14,9 @@
 import qualified Data.Text                     as T
 import qualified Data.Text.Lazy                as TL
 import           Prelude.Compat
-import           Text.RE
 import           Text.RE.ZeInternals.Types.CaptureID
 import           Text.RE.ZeInternals.Types.Match
+import           Text.RE.ZeInternals.Types.Matches
 import           Unsafe.Coerce
 
 
diff --git a/Text/RE/ZeInternals/Lex.lhs b/Text/RE/ZeInternals/Lex.lhs
new file mode 100644
--- /dev/null
+++ b/Text/RE/ZeInternals/Lex.lhs
@@ -0,0 +1,45 @@
+\begin{code}
+{-# LANGUAGE NoImplicitPrelude          #-}
+
+module Text.RE.ZeInternals.Lex
+  ( alex
+  , alex'
+  ) where
+
+import           Prelude.Compat
+import           Text.RE.Replace
+import           Text.RE.ZeInternals.Types.IsRegex
+
+
+-- | a simple regex-based scanner interpretter for prototyping
+-- scanners
+alex :: IsRegex re s => [(re,Match s->Maybe t)] -> t -> s -> [t]
+alex = alex' matchOnce
+
+-- | a higher order version of 'alex' parameterised over the @matchOnce@
+-- function
+alex' :: Replace s
+      => (re->s->Match s)
+      -> [(re,Match s->Maybe t)]
+      -> t
+      -> s
+      -> [t]
+alex' mo al t_err = loop
+  where
+    loop s = case lengthR s == 0 of
+      True  -> []
+      False -> choose al s
+
+    choose []           _ = [t_err]
+    choose ((re,f):al') s = case mb_p of
+        Just (s',t) -> t : loop s'
+        _           -> choose al' s
+      where
+        mb_p = do
+          cap <- matchCapture mtch
+          case captureOffset cap == 0 of
+            True  -> (,) (captureSuffix cap) <$> f mtch
+            False -> Nothing
+
+        mtch = mo re s
+\end{code}
diff --git a/Text/RE/ZeInternals/NamedCaptures.lhs b/Text/RE/ZeInternals/NamedCaptures.lhs
--- a/Text/RE/ZeInternals/NamedCaptures.lhs
+++ b/Text/RE/ZeInternals/NamedCaptures.lhs
@@ -27,11 +27,10 @@
 import           GHC.Generics
 import qualified Language.Haskell.TH          as TH
 import           Language.Haskell.TH.Quote
-import           Text.RE
+import           Text.RE.ZeInternals.Lex
 import           Text.RE.ZeInternals.PreludeMacros
 import           Text.RE.ZeInternals.QQ
 import           Text.RE.ZeInternals.TestBench
-import           Text.RE.Tools.Lex
 import           Text.RE.ZeInternals.Types.CaptureID
 import           Text.RE.ZeInternals.Types.Match
 import           Text.Regex.TDFA
diff --git a/Text/RE/ZeInternals/SearchReplace/TDFAEdPrime.hs b/Text/RE/ZeInternals/SearchReplace/TDFAEdPrime.hs
--- a/Text/RE/ZeInternals/SearchReplace/TDFAEdPrime.hs
+++ b/Text/RE/ZeInternals/SearchReplace/TDFAEdPrime.hs
@@ -16,12 +16,12 @@
 import           Language.Haskell.TH
 import           Language.Haskell.TH.Quote
 import           Prelude.Compat
+import           Text.RE.REOptions
+import           Text.RE.Replace
 import           Text.RE.ZeInternals.SearchReplace
 import           Text.RE.ZeInternals.QQ
 import           Text.RE.ZeInternals.TDFA
-import           Text.RE.IsRegex
-import           Text.RE.REOptions
-import           Text.RE.Replace
+import           Text.RE.ZeInternals.Types.IsRegex
 import           Text.Regex.TDFA
 
 
diff --git a/Text/RE/ZeInternals/TDFA.hs b/Text/RE/ZeInternals/TDFA.hs
--- a/Text/RE/ZeInternals/TDFA.hs
+++ b/Text/RE/ZeInternals/TDFA.hs
@@ -69,16 +69,16 @@
 import           Language.Haskell.TH
 import           Language.Haskell.TH.Quote
 import           Prelude.Compat
-import           Text.RE.IsRegex
 import           Text.RE.REOptions
 import           Text.RE.ZeInternals.EscapeREString
 import           Text.RE.ZeInternals.NamedCaptures
 import           Text.RE.ZeInternals.PreludeMacros
-import           Text.RE.ZeInternals.Replace
 import           Text.RE.ZeInternals.QQ
+import           Text.RE.ZeInternals.Replace
 import           Text.RE.ZeInternals.SearchReplace
 import           Text.RE.ZeInternals.TestBench
 import           Text.RE.ZeInternals.Types.CaptureID
+import           Text.RE.ZeInternals.Types.IsRegex
 import           Text.Regex.TDFA
 
 
diff --git a/Text/RE/ZeInternals/TestBench.lhs b/Text/RE/ZeInternals/TestBench.lhs
--- a/Text/RE/ZeInternals/TestBench.lhs
+++ b/Text/RE/ZeInternals/TestBench.lhs
@@ -28,7 +28,6 @@
   , runTests
   , runTests'
   , formatMacroTable
-  , dumpMacroTable
   , formatMacroSummary
   , formatMacroSources
   , formatMacroSource
@@ -59,8 +58,7 @@
 type TestBenchMatcher =
     String -> MacroEnv -> MacroDescriptor -> Matches String
 
--- | what kind of back end will be compiling the RE, and its match
--- function
+-- | what flavour of regex are we dealing with
 data RegexType
   = TDFA TestBenchMatcher
   | PCRE TestBenchMatcher
@@ -228,20 +226,8 @@
 \end{code}
 
 
-dumpMacroTable, formatMacroTable, formatMacroSummary, formatMacroSources, formatMacroSource
--------------------------------------------------------------------------------------------
-
-\begin{code}
--- | dump a MacroEnv into the docs directory
-dumpMacroTable :: FilePath
-               -> FilePath
-               -> RegexType
-               -> MacroEnv
-               -> IO ()
-dumpMacroTable fp_t fp_s rty m_env = do
-  writeFile fp_t $ formatMacroTable   rty              m_env
-  writeFile fp_s $ formatMacroSources rty ExclCaptures m_env
-\end{code}
+formatMacroTable, formatMacroSummary, formatMacroSources, formatMacroSource
+---------------------------------------------------------------------------
 
 \begin{code}
 -- | format a macros table as a markdown table
diff --git a/Text/RE/ZeInternals/Types/IsRegex.lhs b/Text/RE/ZeInternals/Types/IsRegex.lhs
new file mode 100644
--- /dev/null
+++ b/Text/RE/ZeInternals/Types/IsRegex.lhs
@@ -0,0 +1,68 @@
+\begin{code}
+{-# LANGUAGE RecordWildCards            #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE AllowAmbiguousTypes        #-}
+{-# LANGUAGE CPP                        #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
+#endif
+
+module Text.RE.ZeInternals.Types.IsRegex
+  ( IsRegex(..)
+  , SearchReplace(..)
+  , searchReplaceAll
+  , searchReplaceFirst
+  ) where
+
+import           Text.RE.REOptions
+import           Text.RE.Replace
+import           Text.RE.ZeInternals.EscapeREString
+import           Text.RE.ZeInternals.Types.SearchReplace
+\end{code}
+
+\begin{code}
+-- | the 'IsRegex' class allows polymorhic tools to be written that
+-- will work with a variety of regex back ends and text types
+class Replace s => IsRegex re s where
+  -- | finding the first match
+  matchOnce             :: re -> s -> Match s
+  -- | finding all matches
+  matchMany             :: re -> s -> Matches s
+  -- | compiling an RE, failing if the RE is not well formed
+  makeRegex             :: (Functor m,Monad m) => s -> m re
+  -- | comiling an RE, specifying the 'SimpleREOptions'
+  makeRegexWith         :: (Functor m,Monad m) => SimpleREOptions -> s -> m re
+  -- | compiling a 'SearchReplace' template from the RE text and the template Text, failing if they are not well formed
+  makeSearchReplace     :: (Functor m,Monad m,IsRegex re s) => s -> s -> m (SearchReplace re s)
+  -- | compiling a 'SearchReplace' template specifing the 'SimpleREOptions' for the RE
+  makeSearchReplaceWith :: (Functor m,Monad m,IsRegex re s) => SimpleREOptions -> s -> s -> m (SearchReplace re s)
+  -- | incorporate an escaped string into a compiled RE with the default options
+  makeEscaped           :: (Functor m,Monad m) => (s->s) -> s -> m re
+  -- | incorporate an escaped string into a compiled RE with the specified 'SimpleREOptions'
+  makeEscapedWith       :: (Functor m,Monad m) => SimpleREOptions -> (s->s) -> s -> m re
+  -- | extract the text of the RE from the RE
+  regexSource           :: re -> s
+
+  makeRegex           = makeRegexWith         minBound
+  makeSearchReplace   = makeSearchReplaceWith minBound
+  makeEscaped         = makeEscapedWith       minBound
+  makeEscapedWith o f = makeRegexWith o . f . packR . escapeREString . unpackR
+
+-- | search and replace all matches in the argument text; e.g., this function
+-- will convert every YYYY-MM-DD format date in its argument text into a
+-- DD\/MM\/YYYY date:
+--
+--   @searchReplaceAll [ed|${y}([0-9]{4})-0*${m}([0-9]{2})-0*${d}([0-9]{2})\/\/\/${d}\/${m}\/${y}|]@
+--
+searchReplaceAll :: IsRegex re s => SearchReplace re s -> s -> s
+searchReplaceAll SearchReplace{..} = replaceAll getTemplate . matchMany getSearch
+
+-- | search and replace the first occurrence only (if any) in the input text
+-- e.g., to prefix the first string of four hex digits in the imput text,
+-- if any, with @0x@:
+--
+--  @searchReplaceFirst [ed|[0-9A-Fa-f]{4}\/\/\/0x$0|]@
+--
+searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s
+searchReplaceFirst SearchReplace{..} = replace    getTemplate . matchOnce getSearch
+\end{code}
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,5 +1,9 @@
 -*-change-log-*-
 
+0.12.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-31
+  * Add Text.RE.REOptions to RE.Summa (#103)
+  * Move IsRegex into Text.RE (#104)
+
 0.11.1.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-30
   * Cannot hide Text.RE.ZeInternals.SearchReaplace modules (#101)
 
diff --git a/regex.cabal b/regex.cabal
--- a/regex.cabal
+++ b/regex.cabal
@@ -1,5 +1,5 @@
 Name:                   regex
-Version:                0.11.1.0
+Version:                0.12.0.0
 Synopsis:               Toolkit for regex-base
 Description:            A regular expression toolkit for regex-base with
                         compile-time checking of RE syntax, data types for
@@ -32,7 +32,7 @@
 Source-Repository this
     Type:               git
     Location:           https://github.com/iconnect/regex.git
-    Tag:                0.11.1.0
+    Tag:                0.12.0.0
 
 
 
@@ -42,7 +42,6 @@
 
     Exposed-Modules:
       Text.RE
-      Text.RE.IsRegex
       Text.RE.REOptions
       Text.RE.Replace
       Text.RE.Summa
@@ -62,11 +61,11 @@
       Text.RE.ZeInternals
       Text.RE.ZeInternals.AddCaptureNames
       Text.RE.ZeInternals.EscapeREString
+      Text.RE.ZeInternals.Lex
       Text.RE.ZeInternals.NamedCaptures
       Text.RE.ZeInternals.PreludeMacros
       Text.RE.ZeInternals.QQ
       Text.RE.ZeInternals.Replace
-      Text.RE.ZeInternals.Types.SearchReplace
       Text.RE.ZeInternals.SearchReplace
       Text.RE.ZeInternals.SearchReplace.TDFA
       Text.RE.ZeInternals.SearchReplace.TDFA.ByteString
@@ -80,9 +79,11 @@
       Text.RE.ZeInternals.TestBench
       Text.RE.ZeInternals.Types.Capture
       Text.RE.ZeInternals.Types.CaptureID
+      Text.RE.ZeInternals.Types.IsRegex
       Text.RE.ZeInternals.Types.LineNo
       Text.RE.ZeInternals.Types.Match
       Text.RE.ZeInternals.Types.Matches
+      Text.RE.ZeInternals.Types.SearchReplace
 
     Default-Language:   Haskell2010
 
