diff --git a/getopt-generics.cabal b/getopt-generics.cabal
--- a/getopt-generics.cabal
+++ b/getopt-generics.cabal
@@ -1,9 +1,9 @@
--- This file has been generated from package.yml by hpack version 0.2.0.
+-- This file has been generated from package.yaml by hpack version 0.3.2.
 --
 -- see: https://github.com/sol/hpack
 
 name:           getopt-generics
-version:        0.7.1
+version:        0.7.1.1
 synopsis:       Simple command line argument parsing
 description:    "getopt-generics" tries to make it very simple to create command line argument parsers. An introductory example can be found in the <https://github.com/zalora/getopt-generics#getopt-generics README>.
 category:       Console, System
@@ -48,10 +48,13 @@
       System.Console.GetOpt.Generics.Result
       System.Console.GetOpt.Generics
       ExamplesSpec
+      ModifiersSpec.UseForPositionalArgumentsSpec
+      ModifiersSpec
       System.Console.GetOpt.Generics.InternalSpec
       System.Console.GetOpt.Generics.ModifierSpec
       System.Console.GetOpt.Generics.ResultSpec
       System.Console.GetOpt.GenericsSpec
+      Util
       Example
       Readme
   build-depends:
diff --git a/src/System/Console/GetOpt/Generics.hs b/src/System/Console/GetOpt/Generics.hs
--- a/src/System/Console/GetOpt/Generics.hs
+++ b/src/System/Console/GetOpt/Generics.hs
@@ -38,6 +38,8 @@
   -- * Re-exports from "Generics.SOP"
   Generic,
   HasDatatypeInfo,
+  All2,
+  Code,
   Proxy(..)
  ) where
 
@@ -113,7 +115,7 @@
         err typeName "constructors without field labels"
   where
     err typeName message =
-      Errors ["getopt-generics doesn't support " ++ message ++
+      errors ["getopt-generics doesn't support " ++ message ++
               " (" ++ typeName ++ ")."]
 
 data Field a
@@ -136,7 +138,7 @@
     let (withPositionalArguments, additionalArgumentsErrors) =
           fillInPositionalArguments arguments $
             project options initialFieldStates
-    either Errors return additionalArgumentsErrors
+    either errors return additionalArgumentsErrors
 
     to . SOP . Z <$> collectResult withPositionalArguments
   where
@@ -146,7 +148,7 @@
     reportGetOptErrors :: [String] -> Result ()
     reportGetOptErrors parseErrors = case parseErrors of
       [] -> pure ()
-      errs -> Errors errs
+      errs -> errors errs
 
 -- Creates a list of NS where every element corresponds to one field. To be
 -- used by 'getOpt'.
@@ -191,7 +193,7 @@
     then case cast (id :: FieldState x -> FieldState x) of
       (Just id' :: Maybe (FieldState [String] -> FieldState x)) ->
         Success $ id' PositionalArguments
-      Nothing -> Errors
+      Nothing -> errors
         ["UseForPositionalArguments can only be used " ++
          "for fields of type [String] not " ++
          show (typeOf (impossible "mkInitialFieldStates" :: x))]
@@ -211,12 +213,11 @@
     case (\ (a, b, c) -> (sort a, b, c)) (getOpt Permute options args) of
       ([], _, _) -> return ()
         -- no help or version flag given
-      (HelpFlag : _, _, _) -> OutputAndExit $
-        stripTrailingSpaces $
+      (HelpFlag : _, _, _) -> outputAndExit $
         usageInfo header $
           toOptDescrUnit (mkOptDescrs modifiers fields) ++
           toOptDescrUnit options
-      (VersionFlag version : _, _, _) -> OutputAndExit $
+      (VersionFlag version : _, _, _) -> outputAndExit $
         progName ++ " version " ++ version ++ "\n"
   where
     options :: [OptDescr OutputInfoFlag]
@@ -248,11 +249,6 @@
 positionalArgumentHelp (_ :* r) = positionalArgumentHelp r
 positionalArgumentHelp Nil = []
 
-stripTrailingSpaces :: String -> String
-stripTrailingSpaces = unlines . map stripLines . lines
-  where
-    stripLines = reverse . dropWhile isSpace . reverse
-
 -- Fills in the positional arguments in the NP that already contains the flag
 -- values. Fills in FieldErrors in case of
 -- - parse errors and
@@ -298,8 +294,8 @@
     inner :: FieldState x -> Result x
     inner s = case s of
       FieldSuccess v -> Success v
-      FieldErrors errs -> Errors errs
-      Unset err -> Errors [err]
+      FieldErrors errs -> errors errs
+      Unset err -> errors [err]
       PositionalArguments -> impossible "collectResult"
       PositionalArgument -> impossible "collectResult"
 
diff --git a/src/System/Console/GetOpt/Generics/Modifier.hs b/src/System/Console/GetOpt/Generics/Modifier.hs
--- a/src/System/Console/GetOpt/Generics/Modifier.hs
+++ b/src/System/Console/GetOpt/Generics/Modifier.hs
@@ -58,7 +58,7 @@
 data Modifiers = Modifiers {
   _shortOptions :: [(String, [Char])],
   _renamings :: [(String, String)],
-  positionalArgumentsField :: Maybe (String, String),
+  positionalArgumentsField :: [(String, String)],
   helpTexts :: [(String, String)],
   version :: Maybe String
  }
@@ -68,7 +68,7 @@
 mkModifiers = foldM inner empty
   where
     empty :: Modifiers
-    empty = Modifiers [] [] Nothing [] Nothing
+    empty = Modifiers [] [] [] [] Nothing
 
     inner :: Modifiers -> Modifier -> Result Modifiers
     inner (Modifiers shorts renamings args help version) modifier = case modifier of
@@ -82,7 +82,7 @@
         return $ Modifiers shorts (insert fromNormalized to renamings) args help version
       (UseForPositionalArguments option typ) -> do
         normalized <- normalizeFieldName option
-        return $ Modifiers shorts renamings (Just (normalized, map toUpper typ)) help version
+        return $ Modifiers shorts renamings ((normalized, map toUpper typ) : args) help version
       (AddOptionHelp option helpText) -> do
         normalized <- normalizeFieldName option
         return $ Modifiers shorts renamings args (insert normalized helpText help) version
@@ -98,14 +98,14 @@
   fromMaybe option (lookup option renamings)
 
 hasPositionalArgumentsField :: Modifiers -> Bool
-hasPositionalArgumentsField = isJust . positionalArgumentsField
+hasPositionalArgumentsField = not . null . positionalArgumentsField
 
 isPositionalArgumentsField :: Modifiers -> String -> Bool
 isPositionalArgumentsField modifiers field =
-  Just field == fmap fst (positionalArgumentsField modifiers)
+  any (field ==) (map fst (positionalArgumentsField modifiers))
 
 getPositionalArgumentType :: Modifiers -> Maybe String
-getPositionalArgumentType = fmap snd . positionalArgumentsField
+getPositionalArgumentType = fmap snd . listToMaybe . positionalArgumentsField
 
 getHelpText :: Modifiers -> String -> String
 getHelpText modifiers field = fromMaybe "" (lookup field (helpTexts modifiers))
diff --git a/src/System/Console/GetOpt/Generics/Result.hs b/src/System/Console/GetOpt/Generics/Result.hs
--- a/src/System/Console/GetOpt/Generics/Result.hs
+++ b/src/System/Console/GetOpt/Generics/Result.hs
@@ -1,6 +1,11 @@
 {-# LANGUAGE DeriveFunctor #-}
 
-module System.Console.GetOpt.Generics.Result where
+module System.Console.GetOpt.Generics.Result (
+  Result(..),
+  errors,
+  outputAndExit,
+  handleResult,
+ ) where
 
 import           Prelude ()
 import           Prelude.Compat
@@ -26,6 +31,12 @@
     -- ^ The CLI was used with @--help@. The 'Result' contains the help message.
   deriving (Show, Eq, Ord, Functor)
 
+errors :: [String] -> Result a
+errors = Errors . map removeTrailingNewline
+
+outputAndExit :: String -> Result a
+outputAndExit = OutputAndExit . stripTrailingSpaces
+
 instance Applicative Result where
   pure = Success
   OutputAndExit message <*> _ = OutputAndExit message
@@ -57,3 +68,16 @@
 addNewlineIfMissing s
   | "\n" `isSuffixOf` s = s
   | otherwise = s ++ "\n"
+
+removeTrailingNewline :: String -> String
+removeTrailingNewline s
+  | "\n" `isSuffixOf` s = init s
+  | otherwise = s
+
+stripTrailingSpaces :: String -> String
+stripTrailingSpaces = reverse . inner . dropWhile (== ' ') . reverse
+  where
+    inner s = case s of
+      ('\n' : ' ' : r) -> inner ('\n' : r)
+      (a : r) -> a : inner r
+      [] -> []
diff --git a/test/ModifiersSpec.hs b/test/ModifiersSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ModifiersSpec.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE DeriveGeneric #-}
+
+module ModifiersSpec where
+
+import           Data.List
+import           Test.Hspec
+import           Test.Hspec.Expectations.Contrib
+
+import           System.Console.GetOpt.Generics
+import           System.Console.GetOpt.GenericsSpec
+import           Util
+
+spec :: Spec
+spec = do
+  describe "AddShortOption" $ do
+    it "allows modifiers for short options" $ do
+      modsParse [AddShortOption "camel-case" 'x'] "-x foo"
+        `shouldBe` Success (CamelCaseOptions "foo")
+
+    it "allows modifiers in camelCase" $ do
+      modsParse [AddShortOption "camelCase" 'x'] "-x foo"
+        `shouldBe` Success (CamelCaseOptions "foo")
+
+    let parse' :: String -> Result CamelCaseOptions
+        parse' = modsParse [AddShortOption "camelCase" 'x']
+    it "includes the short option in the help" $ do
+      let OutputAndExit output = parse' "--help"
+      output `shouldContain` "-x STRING"
+
+  describe "RenameOption" $ do
+    it "allows to rename options" $ do
+      modsParse [RenameOption "camelCase" "bla"] "--bla foo"
+        `shouldBe` Success (CamelCaseOptions "foo")
+
+    let parse' = modsParse [RenameOption "camelCase" "foo", RenameOption "camelCase" "bar"]
+    it "allows to shadow earlier modifiers with later modifiers" $ do
+      parse' "--bar foo" `shouldBe` Success (CamelCaseOptions "foo")
+      let Errors errs = parse' "--foo foo"
+      show errs `shouldContain` "unknown argument: foo"
+
+    it "contains renamed options in error messages" $ do
+      let Errors errs = parse' []
+      show errs `shouldNotContain` "camelCase"
+      show errs `shouldContain` "camel-case"
+
+    it "allows to address fields in Modifiers in slugified form" $ do
+      modsParse [RenameOption "camel-case" "foo"] "--foo bar"
+        `shouldBe` Success (CamelCaseOptions "bar")
+
+  describe "AddVersionFlag" $ do
+    it "implements --version" $ do
+      let OutputAndExit output = modsParse [AddVersionFlag "1.0.0"] "--version" :: Result Foo
+      output `shouldBe` "prog-name version 1.0.0\n"
+
+    it "--help takes precedence over --version" $ do
+      let OutputAndExit output = modsParse [AddVersionFlag "1.0.0"] "--version --help" :: Result Foo
+      output `shouldSatisfy` ("show help and exit" `isInfixOf`)
+
+    it "--version shows up in help output" $ do
+      let OutputAndExit output = modsParse [AddVersionFlag "1.0.0"] "--help" :: Result Foo
+      output `shouldSatisfy` ("show version and exit" `isInfixOf`)
diff --git a/test/ModifiersSpec/UseForPositionalArgumentsSpec.hs b/test/ModifiersSpec/UseForPositionalArgumentsSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/ModifiersSpec/UseForPositionalArgumentsSpec.hs
@@ -0,0 +1,69 @@
+{-# LANGUAGE DeriveGeneric #-}
+
+module ModifiersSpec.UseForPositionalArgumentsSpec where
+
+import           Data.List
+import qualified GHC.Generics as GHC
+import           Test.Hspec
+
+import           System.Console.GetOpt.Generics
+import           Util
+
+data WithPositionalArguments
+  = WithPositionalArguments {
+    positionalArguments :: [String],
+    someFlag :: Bool
+  }
+  deriving (GHC.Generic, Show, Eq)
+
+instance Generic WithPositionalArguments
+instance HasDatatypeInfo WithPositionalArguments
+
+data WithMultiplePositionalArguments
+  = WithMultiplePositionalArguments {
+    positionalArgumentsA :: [String],
+    positionalArgumentsB :: [String],
+    someOtherFlag :: Bool
+  }
+  deriving (GHC.Generic, Show, Eq)
+
+instance Generic WithMultiplePositionalArguments
+instance HasDatatypeInfo WithMultiplePositionalArguments
+
+spec :: Spec
+spec = do
+  it "allows positionalArguments" $ do
+    modsParse
+      [UseForPositionalArguments "positionalArguments" "type"]
+      "foo bar --some-flag"
+        `shouldBe` Success (WithPositionalArguments ["foo", "bar"] True)
+
+  it "disallows to specify the option used for positional arguments" $ do
+    modsParse
+      [UseForPositionalArguments "positionalArguments" "type"]
+      "--positional-arguments foo"
+        `shouldBe`
+      (Errors ["unrecognized option `--positional-arguments'"]
+        :: Result WithPositionalArguments)
+
+  it "complains about fields that don't have type [String]" $ do
+    modsParse
+      [UseForPositionalArguments "someFlag" "type"]
+      "doesn't matter"
+        `shouldBe`
+      (Errors ["UseForPositionalArguments can only be used for fields of type [String] not Bool"]
+        :: Result WithPositionalArguments)
+
+  it "includes the type of positional arguments in the help output in upper-case" $ do
+    let OutputAndExit output = modsParse
+          [UseForPositionalArguments "positionalArguments" "foo"]
+          "--help" :: Result WithPositionalArguments
+    output `shouldSatisfy` ("prog-name [OPTIONS] [FOO]\n" `isPrefixOf`)
+
+  it "complains about multiple PositionalArguments fields" $ do
+    let modifiers =
+          UseForPositionalArguments "positionalArgumentsA" "foo" :
+          UseForPositionalArguments "positionalArgumentsB" "bar" :
+          []
+    (modsParse modifiers [] :: Result WithMultiplePositionalArguments)
+      `shouldBe` Errors ["UseForPositionalArguments can only be used once"]
diff --git a/test/System/Console/GetOpt/Generics/ResultSpec.hs b/test/System/Console/GetOpt/Generics/ResultSpec.hs
--- a/test/System/Console/GetOpt/Generics/ResultSpec.hs
+++ b/test/System/Console/GetOpt/Generics/ResultSpec.hs
@@ -3,10 +3,12 @@
 module System.Console.GetOpt.Generics.ResultSpec where
 
 import           Control.Exception
+import           Data.List
 import           System.Exit
 import           System.IO
 import           System.IO.Silently
 import           Test.Hspec
+import           Test.QuickCheck hiding (Result(..))
 
 import           System.Console.GetOpt.Generics.Result
 
@@ -18,6 +20,33 @@
         (Errors ["foo"] >> Errors ["bar"] :: Result ())
           `shouldBe` Errors ["foo", "bar"]
 
+  describe "errors" $ do
+    it "removes trailing newlines" $ do
+      (errors ["foo\n", "bar", "baz\n"] :: Result ()) `shouldBe`
+        Errors ["foo", "bar", "baz"]
+
+  describe "outputAndExit" $ do
+    it "removes trailing spaces" $ do
+      (outputAndExit "foo \nbar" :: Result ()) `shouldBe`
+        OutputAndExit "foo\nbar"
+
+    it "removes trailing spaces at the end" $ do
+      (outputAndExit "foo " :: Result ()) `shouldBe`
+        OutputAndExit "foo"
+
+    it "quickcheck" $ do
+      property $ \ s ->
+        let OutputAndExit output = outputAndExit s
+        in output `shouldSatisfy` (not . (" \n" `isInfixOf`))
+
+    it "only strips spaces" $ do
+      property $ \ s ->
+        let OutputAndExit output = outputAndExit s
+        in
+          filter (/= ' ') output
+            `shouldBe`
+          filter (/= ' ') s
+
   describe "handleResult" $ do
     it "appends '\\n' at the end of error messages if missing" $ do
       output <- hCapture_ [stderr] $ do
@@ -25,3 +54,13 @@
           _ <- handleResult (Errors ["foo", "bar\n", "baz"])
           return ()
       output `shouldBe` "foo\nbar\nbaz\n"
+
+    context "OutputAndExit" $ do
+      it "throws ExitSuccess" $ do
+        handleResult (OutputAndExit "foo")
+          `shouldThrow` (== ExitSuccess)
+
+    context "Errors" $ do
+      it "throws an ExitFailure" $ do
+        handleResult (Errors ["foo"])
+          `shouldThrow` (== ExitFailure 1)
diff --git a/test/System/Console/GetOpt/GenericsSpec.hs b/test/System/Console/GetOpt/GenericsSpec.hs
--- a/test/System/Console/GetOpt/GenericsSpec.hs
+++ b/test/System/Console/GetOpt/GenericsSpec.hs
@@ -1,5 +1,6 @@
-{-# LANGUAGE DeriveDataTypeable  #-}
-{-# LANGUAGE DeriveGeneric       #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module System.Console.GetOpt.GenericsSpec where
@@ -7,20 +8,17 @@
 import           Prelude ()
 import           Prelude.Compat
 
-import           Control.Exception
 import           Data.Foldable (forM_)
-import           Data.List (isInfixOf, isPrefixOf, isSuffixOf)
+import           Data.List (isPrefixOf, isSuffixOf)
 import           Data.Typeable
 import qualified GHC.Generics as GHC
 import           System.Environment
-import           System.Exit
-import           System.IO
-import           System.IO.Silently
 import           Test.Hspec
 import           Test.Hspec.Expectations.Contrib
 import           Test.QuickCheck hiding (Result(..))
 
 import           System.Console.GetOpt.Generics
+import           Util
 
 spec :: Spec
 spec = do
@@ -30,8 +28,6 @@
   part4
   part5
   part6
-  part7
-  part8
 
 data Foo
   = Foo {
@@ -59,60 +55,41 @@
       withArgs (words "--bar 4 --baz foo") $
         getArguments `shouldReturn` Foo (Just 4) "foo" False
 
+  describe "parseArguments" $ do
     it "allows optional arguments" $ do
-      withArgs (words "--baz foo") $
-        getArguments `shouldReturn` Foo Nothing "foo" False
+      parse "--baz foo" `shouldBe`
+        Success (Foo Nothing "foo" False)
 
     it "allows boolean flags" $ do
-      withArgs (words "--bool --baz foo") $
-        getArguments `shouldReturn` Foo Nothing "foo" True
+      parse "--bool --baz foo" `shouldBe`
+        Success (Foo Nothing "foo" True)
 
     context "with invalid arguments" $ do
-      it "doesn't execute the action" $ do
-        let main = withArgs (words "--invalid") $ do
-              _ :: Foo <- getArguments
-              throwIO (ErrorCall "action")
-        main `shouldThrow` (== ExitFailure 1)
-
       it "prints out an error" $ do
-        output <- hCapture_ [stderr] $ handle (\ (_ :: SomeException) -> return ()) $
-          withArgs (words "--no-such-option") $ do
-            _ :: Foo <- getArguments
-            return ()
-        output `shouldBe` "unrecognized option `--no-such-option'\nmissing option: --baz=STRING\n"
+        let Errors messages = parse "--no-such-option" :: Result Foo
+        messages `shouldBe`
+          ["unrecognized option `--no-such-option'",
+           "missing option: --baz=STRING"]
 
       it "prints errors for missing options" $ do
-        output <- hCapture_ [stderr] $ handle (\ (_ :: SomeException) -> return ()) $
-          withArgs [] $ do
-            _ :: Foo <- getArguments
-            return ()
-        output `shouldContain` "missing option: --baz=STRING"
-        output `shouldSatisfy` ("\n" `isSuffixOf`)
+        let Errors [message] = parse [] :: Result Foo
+        message `shouldBe` "missing option: --baz=STRING"
 
       it "prints out an error for unparseable options" $ do
-        output <- hCapture_ [stderr] $ handle (\ (_ :: SomeException) -> return ()) $
-          withArgs (words "--bar foo --baz huhu") $ do
-            _ :: Foo <- getArguments
-            return ()
-        output `shouldBe` "cannot parse as INTEGER (optional): foo\n"
+        let Errors [message] = parse "--bar foo --baz huhu" :: Result Foo
+        message `shouldBe` "cannot parse as INTEGER (optional): foo"
 
       it "complains about unused positional arguments" $ do
-        (parseArguments "prog-name" [] (words "--baz foo unused") :: Result Foo)
+        (parse "--baz foo unused" :: Result Foo)
           `shouldBe` Errors ["unknown argument: unused"]
 
       it "complains about invalid overwritten options" $ do
-        output <- hCapture_ [stderr] $ handle (\ (_ :: SomeException) -> return ()) $
-          withArgs (words "--bar foo --baz huhu --bar 12") $ do
-            _ :: Foo <- getArguments
-            return ()
-        output `shouldBe` "cannot parse as INTEGER (optional): foo\n"
+        let Errors [message] = parse "--bar foo --baz huhu --bar 12" :: Result Foo
+        message `shouldBe` "cannot parse as INTEGER (optional): foo"
 
     context "--help" $ do
       it "implements --help" $ do
-        output <- capture_ $ withArgs ["--help"] $
-          handle (\ (_ :: SomeException) -> return ()) $ do
-            _ :: Foo <- getArguments
-            return ()
+        let OutputAndExit output = parse "--help" :: Result Foo
         mapM_ (output `shouldContain`) $
           "--bar=INTEGER" : "optional" :
           "--baz=STRING" :
@@ -120,42 +97,26 @@
           []
         lines output `shouldSatisfy` (not . ("" `elem`))
 
-      it "throws ExitSuccess" $ do
-        withArgs ["--help"] (getArguments :: IO Foo)
-          `shouldThrow` (== ExitSuccess)
-
       it "contains help message about --help" $ do
-        output <- capture_ $ withArgs ["--help"] $
-          handle (\ (_ :: SomeException) -> return ()) $ do
-            _ :: Foo <- getArguments
-            return ()
+        let OutputAndExit output = parse "--help" :: Result Foo
         output `shouldContain` "show help and exit"
 
       it "does not contain trailing spaces" $ do
-        output <- capture_ $ withArgs ["--help"] $
-          handle (\ (_ :: SomeException) -> return ()) $ do
-            _ :: Foo <- getArguments
-            return ()
+        let OutputAndExit output = parse "--help" :: Result Foo
         forM_ (lines output) $ \ line ->
           line `shouldSatisfy` (not . (" " `isSuffixOf`))
 
-      it "throws an exception when the options datatype is not allowed" $ do
-        output <- hCapture_ [stderr] $
-          withArgs ["--help"] $
-          handle (\ (_ :: SomeException) -> return ()) $ do
-             _ :: NotAllowed <- getArguments
-             return ()
-        output `shouldContain` "getopt-generics doesn't support sum types"
-        lines output `shouldSatisfy` (not . ("" `elem`))
+      it "complains when the options datatype is not allowed" $ do
+        let Errors [message] = parse "--help" :: Result NotAllowed
+        message `shouldSatisfy` ("getopt-generics doesn't support sum types" `isPrefixOf`)
 
       it "outputs a header including \"[OPTIONS]\"" $ do
-        let OutputAndExit output =
-              parseArguments "prog-name" [] ["--help"] :: Result Foo
+        let OutputAndExit output = parse "--help" :: Result Foo
         output `shouldSatisfy` ("prog-name [OPTIONS]\n" `isPrefixOf`)
 
   describe "parseArguments" $ do
     it "allows to overwrite String options" $ do
-      parseArguments "header" [] (words "--baz one --baz two")
+      parse "--baz one --baz two"
         `shouldBe` Success (Foo Nothing "two" False)
 
 data ListOptions
@@ -169,18 +130,15 @@
 
 part2 :: Spec
 part2 = do
-  describe "getArguments" $ do
+  describe "parseArguments" $ do
     it "allows to interpret multiple uses of the same option as lists" $ do
-      withArgs (words "--multiple 23 --multiple 42") $ do
-        getArguments `shouldReturn` ListOptions [23, 42]
+      parse "--multiple 23 --multiple 42"
+        `shouldBe` Success (ListOptions [23, 42])
 
     it "complains about invalid list arguments" $ do
-        output <- hCapture_ [stderr] $
-          withArgs (words "--multiple foo --multiple 13") $
-          handle (\ (_ :: SomeException) -> return ()) $ do
-            _ :: ListOptions <- getArguments
-            return ()
-        output `shouldBe` "cannot parse as INTEGER (multiple possible): foo\n"
+      let Errors errs =
+            parse "--multiple foo --multiple 13" :: Result ListOptions
+      errs `shouldBe` ["cannot parse as INTEGER (multiple possible): foo"]
 
 data CamelCaseOptions
   = CamelCaseOptions {
@@ -193,61 +151,22 @@
 
 part3 :: Spec
 part3 = do
-  describe "getArguments" $ do
+  describe "parseArguments" $ do
     it "turns camelCase selectors to lowercase and seperates with a dash" $ do
-        withArgs (words "--camel-case foo") $ do
-          getArguments `shouldReturn` CamelCaseOptions "foo"
+      parse "--camel-case foo" `shouldBe` Success (CamelCaseOptions "foo")
 
-  describe "parseArguments" $ do
     it "help does not contain camelCase flags" $ do
       let OutputAndExit output :: Result CamelCaseOptions
-            = parseArguments "prog-name" [] ["--help"]
+            = parse "--help"
       output `shouldNotContain` "camelCase"
       output `shouldContain` "camel-case"
 
     it "error messages don't contain camelCase flags" $ do
       let Errors errs :: Result CamelCaseOptions
-            = parseArguments "prog-name" [] ["--bla"]
+            = parse "--bla"
       show errs `shouldNotContain` "camelCase"
       show errs `shouldContain` "camel-case"
 
-    context "AddShortOption" $ do
-      it "allows modifiers for short options" $ do
-        parseArguments "prog-name" [AddShortOption "camel-case" 'x'] (words "-x foo")
-          `shouldBe` Success (CamelCaseOptions "foo")
-
-      it "allows modifiers in camelCase" $ do
-        parseArguments "prog-name" [AddShortOption "camelCase" 'x'] (words "-x foo")
-          `shouldBe` Success (CamelCaseOptions "foo")
-
-      let parse :: [String] -> Result CamelCaseOptions
-          parse = parseArguments "prog-name" [AddShortOption "camelCase" 'x']
-      it "includes the short option in the help" $ do
-        let OutputAndExit output = parse ["--help"]
-        output `shouldContain` "-x STRING"
-
-    context "RenameOption" $ do
-      it "allows to rename options" $ do
-        parseArguments "prog-name" [RenameOption "camelCase" "bla"] (words "--bla foo")
-          `shouldBe` Success (CamelCaseOptions "foo")
-
-      let parse = parseArguments "prog-name"
-            [RenameOption "camelCase" "foo", RenameOption "camelCase" "bar"]
-      it "allows to shadow earlier modifiers with later modifiers" $ do
-        parse (words "--bar foo")
-          `shouldBe` Success (CamelCaseOptions "foo")
-        let Errors errs = parse (words "--foo foo")
-        show errs `shouldContain` "unknown argument: foo"
-
-      it "contains renamed options in error messages" $ do
-        let Errors errs = parse []
-        show errs `shouldNotContain` "camelCase"
-        show errs `shouldContain` "camel-case"
-
-      it "allows to address fields in Modifiers in slugified form" $ do
-        parseArguments "prog-name" [RenameOption "camel-case" "foo"] (words "--foo bar")
-          `shouldBe` Success (CamelCaseOptions "bar")
-
 data WithUnderscore
   = WithUnderscore {
     _withUnderscore :: String
@@ -261,70 +180,9 @@
 part4 = do
   describe "parseArguments" $ do
     it "ignores leading underscores in field names" $ do
-      parseArguments "prog-name" [] (words "--with-underscore foo")
+      parse "--with-underscore foo"
         `shouldBe` Success (WithUnderscore "foo")
 
-data WithPositionalArguments
-  = WithPositionalArguments {
-    positionalArguments :: [String],
-    someFlag :: Bool
-  }
-  deriving (GHC.Generic, Show, Eq)
-
-instance Generic WithPositionalArguments
-instance HasDatatypeInfo WithPositionalArguments
-
-data WithMultiplePositionalArguments
-  = WithMultiplePositionalArguments {
-    positionalArguments1 :: [String],
-    positionalArguments2 :: [String],
-    someOtherFlag :: Bool
-  }
-  deriving (GHC.Generic, Show, Eq)
-
-instance Generic WithMultiplePositionalArguments
-instance HasDatatypeInfo WithMultiplePositionalArguments
-
-part5 :: Spec
-part5 = do
-  describe "parseArguments" $ do
-    context "UseForPositionalArguments" $ do
-      it "allows positionalArguments" $ do
-        parseArguments "prog-name"
-          [UseForPositionalArguments "positionalArguments" "type"]
-          (words "foo bar --some-flag")
-            `shouldBe` Success (WithPositionalArguments ["foo", "bar"] True)
-
-      it "disallows to specify the option used for positional arguments" $ do
-        parseArguments "prog-name"
-          [UseForPositionalArguments "positionalArguments" "type"]
-          (words "--positional-arguments foo")
-            `shouldBe`
-          (Errors ["unrecognized option `--positional-arguments'\n"]
-            :: Result WithPositionalArguments)
-
-      it "complains about fields that don't have type [String]" $ do
-        parseArguments "prog-name"
-          [UseForPositionalArguments "someFlag" "type"]
-          (words "doesn't matter")
-            `shouldBe`
-          (Errors ["UseForPositionalArguments can only be used for fields of type [String] not Bool"]
-            :: Result WithPositionalArguments)
-
-      it "includes the type of positional arguments in the help output in upper-case" $ do
-        let OutputAndExit output = parseArguments "prog-name"
-              [UseForPositionalArguments "positionalArguments" "foo"]
-              (words "--help") :: Result WithPositionalArguments
-        output `shouldSatisfy` ("prog-name [OPTIONS] [FOO]\n" `isPrefixOf`)
-
-      it "complains about multiple PositionalArguments fields" $ do
-        let modifiers =
-              UseForPositionalArguments "positionalArguments1" "foo" :
-              UseForPositionalArguments "positionalArguments2" "bar" :
-              []
-        (parseArguments "prog-name" modifiers [] :: Result WithMultiplePositionalArguments)
-          `shouldBe` Errors ["UseForPositionalArguments can only be used once"]
-
 data CustomFields
   = CustomFields {
     custom :: Custom,
@@ -350,15 +208,13 @@
     "baz" -> Just CBaz
     _ -> Nothing
 
-part6 :: Spec
-part6 = do
+part5 :: Spec
+part5 = do
   describe "parseArguments" $ do
     context "CustomFields" $ do
       it "allows easy implementation of custom field types" $ do
-        parseArguments "prog-name" []
-            (words "--custom foo --custom-list bar --custom-maybe baz")
-          `shouldBe`
-            Success (CustomFields CFoo [CBar] (Just CBaz))
+        parse "--custom foo --custom-list bar --custom-maybe baz"
+          `shouldBe` Success (CustomFields CFoo [CBar] (Just CBaz))
 
 data WithoutSelectors
   = WithoutSelectors String Bool Int
@@ -367,31 +223,31 @@
 instance Generic WithoutSelectors
 instance HasDatatypeInfo WithoutSelectors
 
-part7 :: Spec
-part7 = do
+part6 :: Spec
+part6 = do
   describe "parseArguments" $ do
     context "WithoutSelectors" $ do
       it "populates fields without selectors from positional arguments" $ do
-        parseArguments "prog-name" [] (words "foo true 23")
+        parse "foo true 23"
           `shouldBe` Success (WithoutSelectors "foo" True 23)
 
       it "has good help output for positional arguments" $ do
-        let OutputAndExit output = parseArguments "prog-name" [] ["--help"] :: Result WithoutSelectors
+        let OutputAndExit output = parse "--help" :: Result WithoutSelectors
         output `shouldSatisfy` ("prog-name [OPTIONS] STRING BOOL INTEGER" `isPrefixOf`)
 
       it "has good error messages for missing positional arguments" $ do
-        (parseArguments "prog-name" [] (words "foo") :: Result WithoutSelectors)
+        (parse "foo" :: Result WithoutSelectors)
           `shouldBe` Errors (
             "missing argument of type BOOL" :
             "missing argument of type INTEGER" :
             [])
 
       it "complains about additional positional arguments" $ do
-        (parseArguments "prog-name" [] (words "foo true 5 bar") :: Result WithoutSelectors)
+        (parse "foo true 5 bar" :: Result WithoutSelectors)
           `shouldBe` Errors ["unknown argument: bar"]
 
       it "allows to use tuples" $ do
-        (parseArguments "prog-name" [] (words "42 bar") :: Result (Int, String))
+        (parse "42 bar" :: Result (Int, String))
           `shouldBe` Success (42, "bar")
 
   describe "Option.Bool" $ do
@@ -433,19 +289,3 @@
 
     it "renders as NUMBER in help and error output" $ do
       argumentType (Proxy :: Proxy Float) `shouldBe` "NUMBER"
-
-part8 :: Spec
-part8 = do
-  describe "parseArgument" $ do
-    context "--version" $ do
-      it "implements --version" $ do
-        let OutputAndExit output = parseArguments "foo" [AddVersionFlag "1.0.0"] (words "--version") :: Result Foo
-        output `shouldBe` "foo version 1.0.0\n"
-
-      it "--help takes precedence over --version" $ do
-        let OutputAndExit output = parseArguments "foo" [AddVersionFlag "1.0.0"] (words "--version --help") :: Result Foo
-        output `shouldSatisfy` ("show help and exit" `isInfixOf`)
-
-      it "--version shows up in help output" $ do
-        let OutputAndExit output = parseArguments "foo" [AddVersionFlag "1.0.0"] (words "--help") :: Result Foo
-        output `shouldSatisfy` ("show version and exit" `isInfixOf`)
diff --git a/test/Util.hs b/test/Util.hs
new file mode 100644
--- /dev/null
+++ b/test/Util.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE ConstraintKinds #-}
+
+module Util where
+
+import           System.Console.GetOpt.Generics
+
+parse :: (Generic a, HasDatatypeInfo a, All2 Option (Code a)) =>
+  String -> Result a
+parse = modsParse []
+
+modsParse :: (Generic a, HasDatatypeInfo a, All2 Option (Code a)) =>
+  [Modifier] -> String -> Result a
+modsParse modifiers = parseArguments "prog-name" modifiers . words
