diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,6 @@
+#####   2.4
+  refactor Replace: remove ReplaceCase. Use Once | All hints instead  
+ 
 #####   2.3 
   include missing TestReplaceOpen 
     
@@ -26,4 +29,30 @@
 
 #####   1.7 
   add MatchSame
-                                   
+
+#####   1.6
+  rollup all match fns into one class
+  add Matchf, Pad
+
+#####   1.5
+  rename Match class -> ExplicitMatch
+
+#####   1.4
+  *API changes*
+  changed namespace                                         
+
+#####   1.3
+  fix bug in replace
+  docs
+  base version constraint
+  
+    
+there is no 1.2 version
+  
+#####   1.1
+  refactor Replace  
+  ! buggy replace
+
+#####   1.0
+  initial version 
+  ! buggy replace         
diff --git a/regex-do.cabal b/regex-do.cabal
--- a/regex-do.cabal
+++ b/regex-do.cabal
@@ -1,5 +1,5 @@
 name:                regex-do
-version:             2.3
+version:             2.4
 synopsis:            PCRE wrapper
 description:         format, search, replace (String | ByteString) with PCRE regex. Utf8-safe
 author:              Imants Cekusins
diff --git a/src/Text/Regex/Do/Pcre/Match.hs b/src/Text/Regex/Do/Pcre/Match.hs
--- a/src/Text/Regex/Do/Pcre/Match.hs
+++ b/src/Text/Regex/Do/Pcre/Match.hs
@@ -6,8 +6,6 @@
 
 import qualified Text.Regex.Base.RegexLike as R hiding (makeRegex)
 import Text.Regex.Do.Type.Do
-import Text.Regex.Do.Pcre.Option as O
-import Text.Regex.Do.Type.Reexport
 import Text.Regex.Do.Pcre.Matchf as F
 import Text.Regex.PCRE.Wrap()
 import Text.Regex.Do.Type.Regex_
@@ -72,12 +70,3 @@
 instance Rx_ a b => Match a b [[PosLen]] where
     match = poslen_
 
-
-
--- | tweak Regex with options
-makeRegexOpts::Opt_ a =>
-    [O.Comp] -> [O.Exec] -> Pattern a -> Regex
-makeRegexOpts comp0 exec0 (Pattern pat0) = rx1
-   where c1 = O.comp comp0
-         e1 = O.exec exec0
-         rx1 = R.makeRegexOpts c1 e1 pat0
diff --git a/src/Text/Regex/Do/Pcre/Option.hs b/src/Text/Regex/Do/Pcre/Option.hs
--- a/src/Text/Regex/Do/Pcre/Option.hs
+++ b/src/Text/Regex/Do/Pcre/Option.hs
@@ -9,20 +9,100 @@
 import qualified Text.Regex.PCRE.ByteString as B
 
 
+-- | <http://www.pcre.org/pcre.txt pcre man pages>
+
 data Comp = Blank       -- ^ 'B.compBlank'
-            | Anchored  -- ^ 'B.compAnchored'
-            | Caseless  -- ^ 'B.compCaseless'
-            | Dotall    -- ^ 'B.compDotAll'
-            | Multiline -- ^ 'B.compMultiline'
-            | Utf8      -- ^ 'B.compUTF8'
-            | Ungreedy  -- ^ 'B.compUngreedy'
-   deriving Enum
+            | Anchored  {- ^ 'B.compAnchored'
 
+            the pattern is forced to be "anchored", that is, it
+       is  constrained to match only at the first matching point in the string
+       that is being searched (the "subject string").
 
+       This effect can also  be achieved  by appropriate constructs in the pattern itself. -}
+
+            | Caseless  {- ^ 'B.compCaseless'
+
+            letters in the pattern match both upper  and  lower case  letters.
+
+            It  is  equivalent  to  Perl's /i option, and it can be changed within a pattern by a (?i) option setting.
+
+       In UTF-8 mode,  PCRE always  understands the concept of case for characters whose values are
+       less than 128, so caseless matching is always possible. For  characters with  higher  values,  the concept of case is supported if PCRE is compiled with Unicode property support.
+        If you want  to use  caseless  matching  for  characters 128 and above, you must ensure
+       that PCRE is compiled with Unicode property support  as  well  as  with UTF-8 support.   -}
+
+            | Dotall    {- ^ 'B.compDotAll'
+
+            a dot metacharacter in the pattern matches a  character of any value,
+            including one that indicates a newline.
+
+            However, it only ever matches one character, even if newlines are  coded  as  CRLF.
+
+       Without  this option, a dot does not match when the current position is
+       at a newline.
+
+       This option is equivalent to Perl's /s option, and it can be  changed within a pattern by a (?s) option setting.
+
+       A negative class such as [^a] always matches newline characters, independent of the setting of this option. -}
+
+            | Multiline {- ^ 'B.compMultiline'
+
+            By default, for the purposes of matching "start of line"  and  "end  of
+       line", PCRE treats the subject string as consisting of a single line of
+       characters, even if it actually contains newlines. The "start of  line"
+       metacharacter (^) matches only at the start of the string, and the "end
+       of line" metacharacter ($) matches only at the end of  the  string,  or
+       before  a terminating newline (except when PCRE_DOLLAR_ENDONLY is set).
+       Note, however, that unless PCRE_DOTALL  is  set,  the  "any  character"
+       metacharacter  (.)  does not match at a newline. This behaviour (for ^,
+       $, and dot) is the same as Perl.
+
+       When PCRE_MULTILINE it is set, the "start of line" and  "end  of  line"
+       constructs  match  immediately following or immediately before internal
+       newlines in the subject string, respectively, as well as  at  the  very
+       start  and  end.
+
+       This is equivalent to Perl's /m option, and it can be
+       changed within a pattern by a (?m) option setting.
+
+       If there are no newlines  in  a  subject string, or no occurrences of ^ or $ in a pattern,
+       setting PCRE_MULTILINE has no effect.    -}
+
+            | Utf8      {- ^ 'B.compUTF8'
+
+            This option causes PCRE to regard both the pattern and the  subject  as
+       strings of UTF-8 characters instead of single-byte strings. However, it
+       is available only when PCRE is built to include UTF  support.  If  not,
+       the  use  of  this option provokes an error. Details of how this option
+       changes the behaviour of PCRE are given in the pcreunicode page.     -}
+
+            | Ungreedy  {- ^ 'B.compUngreedy'
+
+            This  option  inverts  the "greediness" of the quantifiers so that they
+       are not greedy by default, but become greedy if followed by "?".
+
+       It can also be set by a (?U) option setting within the pattern.  -}
+   deriving (Eq,Ord,Enum)
+
+
 data Exec = BlankE  -- ^ 'B.execBlank'
-            | NotEmpty  -- ^ 'B.execNotEmpty'
-            | Partial   -- ^ 'B.execPartial'
-   deriving Enum
+            | NotEmpty  {- ^ 'B.execNotEmpty'
+
+            An empty string is not considered to be a valid match if this option is
+       set. If there are alternatives in the pattern, they are tried.  If  all
+       the  alternatives  match  the empty string, the entire match fails. For
+       example, if the pattern
+
+         a?b?
+
+       is applied to a string not beginning with "a" or  "b",  it  matches  an
+       empty  string at the start of the subject. With PCRE_NOTEMPTY set, this
+       match is not valid, so PCRE searches further into the string for occurrences of "a" or "b".        -}
+
+            | Partial   {- ^ 'B.execPartial'
+
+            see PCREPARTIAL(3)  in <http://www.pcre.org/pcre.txt pcre man pages>    -}
+   deriving (Eq,Ord,Enum)
 
 
 compOpt::Comp -> B.CompOption
diff --git a/src/Text/Regex/Do/Pcre/Replace.hs b/src/Text/Regex/Do/Pcre/Replace.hs
--- a/src/Text/Regex/Do/Pcre/Replace.hs
+++ b/src/Text/Regex/Do/Pcre/Replace.hs
@@ -1,12 +1,10 @@
-module Text.Regex.Do.Pcre.Replace(
-    replace,
-    ReplaceCase_(..))  where
+module Text.Regex.Do.Pcre.Replace
+    (Replace(..))  where
 
 import Text.Regex.Base.RegexLike as R
 import Prelude as P
 import Data.ByteString as B
 import qualified Text.Regex.Do.Pcre.Option as O
-import Text.Regex.Do.Pcre.Match as M
 import Text.Regex.Do.Type.Do
 import Text.Regex.Do.Type.Reexport
 import Text.Regex.Do.Pcre.Matchf
@@ -14,8 +12,16 @@
 import Text.Regex.Do.Convert
 import Text.Regex.Do.Type.Regex_
 import Text.Regex.Do.Type.Extract
+import Text.Regex.Do.Type.MatchHint
 
 
+
+type Ro_ rx = (Regex_ rx, Opt_ rx)
+
+rx'::Regex_ rx => Pattern rx -> [O.Comp] -> Pattern Regex
+rx' p0 opt0 = Pattern $ ropt_ p0 opt0 []
+
+
 {- | == dynamic group replace
    custom replacer fn returns replacement value. See 'O.defaultReplacer'
 
@@ -28,11 +34,11 @@
 
     'Once' vs 'All' options
 
-    >>> replace [Once,Utf8] (Pattern "\\w=(\\d{1,3})") replacer $ Body "a=101 b=3 12"
+    >>> replace (Once[]) (Pattern "\\w=(\\d{1,3})") replacer $ Body "a=101 b=3 12"
 
         "a=[сто один] b=3 12"
 
-    >>> replace [All,Utf8] (Pattern "\\w=(\\d{1,3})") replacer $ Body "a=101 b=3 12"
+    >>> replace (All[]) (Pattern "\\w=(\\d{1,3})") replacer $ Body "a=101 b=3 12"
 
         "a=[сто один] b=[three] 12"
 
@@ -41,69 +47,81 @@
 
     for no-regex 'ByteString' replacement see "Text.Regex.Do.Split"
 
-    >>> replace [Once,Utf8] (Pattern "менее") (Replacement  "более") $ Body "менее менее"
+    >>> replace (Once[Utf8]) (Pattern "менее") (Replacement  "более") $ Body "менее менее"
 
     "более менее"
 
-    >>> replace [Once,Utf8] (Pattern "^a\\s") (Replacement "A") $ Body "a bc хол.гор."
+    >>> replace (Once[]) (Pattern "^a\\s") (Replacement "A") $ Body "a bc хол.гор."
 
     "Abc хол.гор."      -}
 
+class Replace hint rx r a where
+    replace::hint [O.Comp] -> Pattern rx -> r a -> Body a -> a
 
-replace::(Rx_ a a, ReplaceCase_ r a, Opt_ a) =>
-    [ReplaceCase] -> Pattern a -> r a -> Body a -> a
-replace case0 p0 r0 b0 = replace_ case0 p1 r0 b0
-    where opt1 = comp case0
-          p1 = addOpt p0 opt1
 
+instance Regex_ rx => Replace Once rx Replacement String where
+    replace opt0@(Once opt1) p0 r0 b0 =
+        let ma1 = marray_ p1 b1::Maybe MatchArray
+            b1 = toByteString <$> b0
+            r1 = toByteString <$> r0
+            isUtf1 = O.Utf8 `P.elem` opt1
+            bs1 = O.replace ma1 r1 b1
+            p1 = rx' p0 opt1
+        in if isUtf1 then toString bs1
+            else vanilla_once p1 r0 b0
 
--- | implementation detail for the curious
-class ReplaceCase_ r a where
-    replace_::[ReplaceCase] -> Pattern Regex -> r a -> Body a -> a
 
-instance ReplaceCase_ Replacement String where
-    replace_ case0 p0 r0 b0 =
-        let ma1 = marray_ p0 b1::Maybe MatchArray
-            ma2 = marray_ p0 b1::[MatchArray]
+instance Regex_ rx => Replace All rx Replacement String where
+    replace opt0@(All opt1) p0 r0 b0 =
+        let ma2 = marray_ p0 b1::[MatchArray]
             b1 = toByteString <$> b0
             r1 = toByteString <$> r0
-            isAll1 = All `P.elem` case0
-            isUtf1 = Utf8 `P.elem` case0
-            bs1 = if isAll1 then O.replace ma2 r1 b1
-                  else O.replace ma1 r1 b1
+            isUtf1 = O.Utf8 `P.elem` opt1
+            bs1 = O.replace ma2 r1 b1
+            p1 = rx' p0 opt1
         in if isUtf1 then toString bs1
-            else vanilla_replace case0 p0 r0 b0
+            else vanilla_all p1 r0 b0
 
 
-instance ReplaceCase_ Replacement ByteString where
-    replace_ = vanilla_replace
+instance Regex_ rx => Replace Once rx Replacement ByteString where
+    replace opt0@(Once opt1) p0 = vanilla_once $ rx' p0 opt1
 
-instance ReplaceCase_ GroupReplacer ByteString where
-    replace_ = vanilla_replace
+instance Regex_ rx => Replace All rx Replacement ByteString where
+    replace opt0@(All opt1) p0 = vanilla_all $ rx' p0 opt1
 
-instance ReplaceCase_ GroupReplacer String where
-    replace_  = vanilla_replace
+instance Regex_ rx => Replace Once rx GroupReplacer ByteString where
+    replace opt0@(Once opt1) p0 = vanilla_once $ rx' p0 opt1
 
+instance Regex_ rx => Replace All rx GroupReplacer ByteString where
+    replace opt0@(All opt1) p0 = vanilla_all $ rx' p0 opt1
 
-vanilla_replace::(O.ReplaceOpen [] r, O.ReplaceOpen Maybe r,
-    Extract' a,Rx_ a a,Opt_ a) =>
-        [ReplaceCase] -> Pattern Regex -> r a -> Body a -> a
-vanilla_replace case0 p0 r0 b0 =
-   let ma1 = marray_ p0 b0::Maybe MatchArray
-       ma2 = marray_ p0 b0:: [MatchArray]
-       isAll1 = All ` P.elem ` case0
-   in if isAll1 then O.replace ma2 r0 b0
-              else O.replace ma1 r0 b0
+instance Regex_ rx => Replace Once rx GroupReplacer String where
+    replace opt0@(Once opt1) p0 = vanilla_once $ rx' p0 opt1
 
+instance Regex_ rx => Replace All rx GroupReplacer String where
+    replace opt0@(All opt1) p0 = vanilla_all $ rx' p0 opt1
 
-addOpt::Opt_ a =>
-    Pattern a -> [O.Comp] -> Pattern Regex
-addOpt pat0 opt0 = Pattern rx1
-    where rx1 = M.makeRegexOpts opt0 [] pat0
 
+type Vanilla_ f r a = (O.ReplaceOpen f r, Extract' a, RegexLike Regex a)
+type Vanilla_once r a = Vanilla_ Maybe r a
+type Vanilla_all r a = Vanilla_ [] r a
 
-comp::[ReplaceCase]-> [O.Comp]
-comp = P.map mapFn . P.filter filterFn
-   where filterFn o1 = o1 `P.elem` [Utf8,Multiline]
-         mapFn Utf8 = O.Utf8
-         mapFn Multiline = O.Multiline
+
+vanilla_once::Vanilla_once r a =>
+        Pattern Regex ->
+        r a ->
+        Body a ->
+            a
+vanilla_once p0 r0 b0 =
+   let ma1 = marray_ p0 b0::Maybe MatchArray
+   in O.replace ma1 r0 b0
+
+
+vanilla_all::Vanilla_all r a =>
+        Pattern Regex ->
+        r a ->
+        Body a ->
+            a
+vanilla_all p0 r0 b0 =
+   let ma2 = marray_ p0 b0:: [MatchArray]
+   in O.replace ma2 r0 b0
diff --git a/src/Text/Regex/Do/Trim.hs b/src/Text/Regex/Do/Trim.hs
--- a/src/Text/Regex/Do/Trim.hs
+++ b/src/Text/Regex/Do/Trim.hs
@@ -5,7 +5,9 @@
 import qualified Data.ByteString as B
 import Text.Regex.Do.Convert
 import Text.Regex.Do.Pcre.Replace
+import Text.Regex.Do.Type.MatchHint
 
+
 {- | removes leading and trailing spaces and tabs   -}
 
 class Trim a where
@@ -13,7 +15,7 @@
 
 
 instance Trim B.ByteString where
-    trim bs1 = replace [All] rx1 repl1 $ Body bs1
+    trim bs1 = replace (All []) rx1 repl1 $ Body bs1
        where repl1 = Replacement B.empty
              rx1 = rxFn "(^[\\s\\t]+)|([\\s\\t]+$)"
              rxFn = Pattern . toByteString
diff --git a/src/Text/Regex/Do/Type/Do.hs b/src/Text/Regex/Do/Type/Do.hs
--- a/src/Text/Regex/Do/Type/Do.hs
+++ b/src/Text/Regex/Do/Type/Do.hs
@@ -1,7 +1,6 @@
 module Text.Regex.Do.Type.Do where
 
 import Text.Regex.Base.RegexLike as R
-import Text.Regex.Do.Type.Reexport
 
 
 -- | see "Text.Regex.Do.Pcre.ReplaceOpen" 'defaultReplacer' for example implementation
@@ -24,12 +23,3 @@
 
 -- | Offset, Length
 type PosLen = (MatchOffset, MatchLength)
-
-
-data ReplaceCase = Once     -- ^ may be omitted
-                | All       -- ^ if both Once and All are passed, All prevails
-                | Utf8
-                | Multiline deriving Eq
-
-
-type Opt_ a = R.RegexMaker Regex CompOption ExecOption a
diff --git a/src/Text/Regex/Do/Type/Regex_.hs b/src/Text/Regex/Do/Type/Regex_.hs
--- a/src/Text/Regex/Do/Type/Regex_.hs
+++ b/src/Text/Regex/Do/Type/Regex_.hs
@@ -1,22 +1,40 @@
 module Text.Regex.Do.Type.Regex_ where
 
-import Text.Regex.Base.RegexLike as R
+import qualified Text.Regex.Base.RegexLike as R
 import Text.Regex.Do.Type.Reexport
 import Data.ByteString
 import Text.Regex.Do.Type.Do
+import Text.Regex.Do.Pcre.Option
 
 
 class Regex_ a where
    r_::Pattern a -> Regex
+   ropt_::Pattern a -> [Comp] -> [Exec] -> Regex
 
+
 instance Regex_ ByteString where
    r_ (Pattern p0) = R.makeRegex p0
+   ropt_ = makeRegexOpts
 
 instance Regex_ String where
    r_ (Pattern p0) = R.makeRegex p0
+   ropt_ = makeRegexOpts
 
 instance Regex_ Regex where
    r_ (Pattern p0) = p0
+   ropt_ (Pattern p0) _ _ = p0
 
 
 type Rx_ a b = (Regex_ a, R.Extract b, R.RegexLike Regex b)
+type Opt_ a = R.RegexMaker Regex CompOption ExecOption a
+
+
+-- | tweak Regex with options
+makeRegexOpts::Opt_ a =>
+    Pattern a ->
+        [Comp] -> [Exec] ->
+            Regex
+makeRegexOpts (Pattern pat0) comp0 exec0 = rx1
+   where c1 = comp comp0
+         e1 = exec exec0
+         rx1 = R.makeRegexOpts c1 e1 pat0
diff --git a/test/TestRegex/TestReplace.hs b/test/TestRegex/TestReplace.hs
--- a/test/TestRegex/TestReplace.hs
+++ b/test/TestRegex/TestReplace.hs
@@ -9,7 +9,8 @@
 import Text.Regex.Do.Convert
 import Data.ByteString as B
 import Debug.Trace
-
+import Text.Regex.Do.Type.MatchHint
+import Text.Regex.Do.Pcre.Option
 
 main::IO()
 main = do
@@ -23,19 +24,19 @@
 doc = hspec $ do
        describe "Pcre.Replace doc" $ do
           it "replaceGroup 1" $ do
-            replace [Once,Utf8] (Pattern "\\w=(\\d{1,3})") replacer (Body "a=101 b=3 12")
+            replace (Once []) (Pattern "\\w=(\\d{1,3})") replacer (Body "a=101 b=3 12")
                 `shouldBe` "a=[сто один] b=3 12"
           it "replaceGroup 2" $ do
-            replace [All,Utf8] (Pattern "\\w=(\\d{1,3})") replacer (Body "a=101 b=3 12")
+            replace (All []) (Pattern "\\w=(\\d{1,3})") replacer (Body "a=101 b=3 12")
                 `shouldBe` "a=[сто один] b=[three] 12"
           it "replace 3" $ do
-            replace [Once,Utf8] (Pattern "менее") (Replacement  "более") (Body "менее менее")
+            replace (Once [Utf8]) (Pattern "менее") (Replacement  "более") (Body "менее менее")
                 `shouldBe` "более менее"
           it "replace 4" $ do
-            replace [All,Utf8] (Pattern "менее") (Replacement  "боле") (Body "менее менее")
+            replace (All[Utf8]) (Pattern "менее") (Replacement  "боле") (Body "менее менее")
                 `shouldBe` "боле боле"
           it "replace 5" $ do
-            replace [Once,Utf8] (Pattern "^a\\s") (Replacement "A") (Body "a bc хол.гор.")
+            replace (Once[]) (Pattern "^a\\s") (Replacement "A") (Body "a bc хол.гор.")
                 `shouldBe` "Abc хол.гор."
 
 
@@ -43,24 +44,24 @@
 onceUtf8 = hspec $ do
        describe "Pcre.Replace Once Utf8" $ do
           it "^a\\s" $ do
-            replace [Once,Utf8] (Pattern "^a\\s") (Replacement "A") (Body "a bc хол.гор.") `shouldBe` "Abc хол.гор."
+            replace (Once[]) (Pattern "^a\\s") (Replacement "A") (Body "a bc хол.гор.") `shouldBe` "Abc хол.гор."
           it "^b\\s" $ do
-            replace [Once,Utf8] (Pattern "^b\\s") (Replacement "A") (Body "a bc хол.гор.") `shouldBe` "a bc хол.гор."
+            replace (Once[]) (Pattern "^b\\s") (Replacement "A") (Body "a bc хол.гор.") `shouldBe` "a bc хол.гор."
 
 
 latinOnceAll::IO()
 latinOnceAll =  hspec $ do
          describe "Pcre.Replace" $ do
             it "Once" $ do
-               runFn [Once] `shouldBe` toByteString "a=text1 b=11 12"
+               runFn1 Once `shouldBe` toByteString "a=text1 b=11 12"
             it "All" $ do
-               runFn [All] `shouldBe` toByteString "a=text1 b=text1 12"
-            where runFn opts =
+               runFn1 All `shouldBe` toByteString "a=text1 b=text1 12"
+            where runFn1 hint1 =
                      let   rx1 = pattern "(?<==)(\\d{2})"
                            body1 = Body $ toByteString haystack1
                            haystack1 = "a=10 b=11 12"
                            repl1  = replacement "text1"
-                     in replace opts rx1 repl1 body1
+                     in replace (hint1 []) rx1 repl1 body1
 
 
 pattern::String -> Pattern ByteString
@@ -75,9 +76,9 @@
 groupReplace =  hspec $ do
          describe "Pcre.Replace group" $ do
             it "Once" $ do
-               runFn1 [Once,Utf8] `shouldBe` "a=[сто один] b=3 12"
+               runFn1 (Once[Utf8]) `shouldBe` "a=[сто один] b=3 12"
             it "All" $ do
-               runFn1 [All,Utf8] `shouldBe` "a=[сто один] b=[three] 12"
+               runFn1 (All[Utf8]) `shouldBe` "a=[сто один] b=[three] 12"
             where runFn1 opts1 =
                      let   rx1 = Pattern "\\w=(\\d{1,3})"
                            body1 = Body "a=101 b=3 12"
