diff --git a/aeson.cabal b/aeson.cabal
--- a/aeson.cabal
+++ b/aeson.cabal
@@ -1,5 +1,5 @@
 name:               aeson
-version:            2.1.0.0
+version:            2.1.1.0
 license:            BSD3
 license-file:       LICENSE
 category:           Text, Web, JSON
@@ -18,7 +18,7 @@
    || ==8.8.4
    || ==8.10.7
    || ==9.0.2
-   || ==9.2.3
+   || ==9.2.4
    || ==9.4.1
 
 synopsis:           Fast JSON parsing and encoding
@@ -99,8 +99,8 @@
     , bytestring        >=0.10.8.1 && <0.12
     , containers        >=0.5.7.1  && <0.7
     , deepseq           >=1.4.2.0  && <1.5
-    , ghc-prim          >=0.5.0.0  && <0.9
-    , template-haskell  >=2.11.0.0 && <2.19
+    , ghc-prim          >=0.5.0.0  && <0.10
+    , template-haskell  >=2.11.0.0 && <2.20
     , text              >=1.2.3.0  && <1.3 || >=2.0 && <2.1
     , time              >=1.6.0.1  && <1.13
 
@@ -132,7 +132,7 @@
     , these                 >=1.1.1.1  && <1.2
     , unordered-containers  >=0.2.10.0 && <0.3
     , uuid-types            >=1.0.5    && <1.1
-    , vector                >=0.12.0.1 && <0.13
+    , vector                >=0.12.0.1 && <0.14
     , witherable            >=0.4.2    && <0.5
 
   ghc-options:      -Wall
@@ -166,6 +166,7 @@
     ErrorMessages
     Functions
     Instances
+    JSONTestSuite
     Options
     Properties
     PropertyGeneric
@@ -175,6 +176,7 @@
     PropertyRTFunctors
     PropertyTH
     PropUtils
+    Regression.Issue967
     SerializationFormatSpec
     Types
     UnitTests
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,12 @@
 For the latest version of this document, please see [https://github.com/haskell/aeson/blob/master/changelog.md](https://github.com/haskell/aeson/blob/master/changelog.md).
 
+### 2.1.1.0
+
+- Add `Data.Aeson.KeyMap.!?` (flipped) alias to `Data.Aeson.KeyMap.lookup`.
+- Add `Data.Aeson.KeyMap.insertWith` function.
+- Use `unsafeDupablePerformIO` instead of incorrect `accursedUnutterablePerformIO` in creation of keys in TH serialisation.
+  This fixes a bug in TH deriving, e.g. when `Strict` pragma was enabled.
+
 ### 2.1.0.0
 
 - Change time instances of types with year (`Day`, `UTCTime`) to require years with at least 4 digits.
diff --git a/src/Data/Aeson/Internal/ByteString.hs b/src/Data/Aeson/Internal/ByteString.hs
--- a/src/Data/Aeson/Internal/ByteString.hs
+++ b/src/Data/Aeson/Internal/ByteString.hs
@@ -13,8 +13,8 @@
 import Foreign.ForeignPtr (ForeignPtr)
 import Data.ByteString.Short (ShortByteString, fromShort)
 import GHC.Exts (Addr#, Ptr (Ptr))
-import Data.ByteString.Internal (accursedUnutterablePerformIO)
 import Data.ByteString.Short.Internal (createFromPtr)
+import System.IO.Unsafe (unsafeDupablePerformIO)
 
 import qualified Data.ByteString as BS
 import qualified Language.Haskell.TH.Lib as TH
@@ -82,6 +82,7 @@
       bs = fromShort sbs
 #endif
 
+-- this is copied verbatim from @bytestring@, but only in recent versions.
 unsafePackLenLiteral :: Int -> Addr# -> ShortByteString
 unsafePackLenLiteral len addr# =
-    accursedUnutterablePerformIO $ createFromPtr (Ptr addr#) len
+    unsafeDupablePerformIO $ createFromPtr (Ptr addr#) len
diff --git a/src/Data/Aeson/KeyMap.hs b/src/Data/Aeson/KeyMap.hs
--- a/src/Data/Aeson/KeyMap.hs
+++ b/src/Data/Aeson/KeyMap.hs
@@ -16,6 +16,7 @@
     -- * Query
     null,
     lookup,
+    (!?),
     size,
     member,
 
@@ -25,6 +26,7 @@
 
     -- ** Insertion
     insert,
+    insertWith,
 
     -- * Deletion
     delete,
@@ -190,6 +192,12 @@
 insert :: Key -> v -> KeyMap v -> KeyMap v
 insert k v tm = KeyMap (M.insert k v (unKeyMap tm))
 
+-- | Insert with a function combining new and old values, taken in that order.
+--
+-- @since 2.1.1.0
+insertWith :: (a -> a -> a) -> Key -> a -> KeyMap a -> KeyMap a
+insertWith f k v m = KeyMap (M.insertWith f k v (unKeyMap m))
+
 -- | Map a function over all values in the map.
 map :: (a -> b) -> KeyMap a -> KeyMap b
 map = fmap
@@ -393,6 +401,12 @@
 insert :: Key -> v -> KeyMap v -> KeyMap v
 insert k v tm = KeyMap (H.insert k v (unKeyMap tm))
 
+-- | Insert with a function combining new and old values, taken in that order.
+--
+-- @since 2.1.1.0
+insertWith :: (a -> a -> a) -> Key -> a -> KeyMap a -> KeyMap a
+insertWith f k v m = KeyMap (H.insertWith f k v (unKeyMap m))
+
 -- | Map a function over all values in the map.
 map :: (a -> b) -> KeyMap a -> KeyMap b
 map = fmap
@@ -548,6 +562,16 @@
 -------------------------------------------------------------------------------
 -- combinators using existing abstractions
 -------------------------------------------------------------------------------
+
+-- | Return the value to which the specified key is mapped,
+-- or Nothing if this map contains no mapping for the key.
+--
+-- This is a flipped version of 'lookup'.
+--
+-- @since 2.1.1.0
+--
+(!?) :: KeyMap v -> Key -> Maybe v
+(!?) m k = lookup k m
 
 -- | Generalized union with combining function.
 alignWith :: (These a b -> c) -> KeyMap a -> KeyMap b -> KeyMap c
diff --git a/src/Data/Aeson/Parser/Internal.hs b/src/Data/Aeson/Parser/Internal.hs
--- a/src/Data/Aeson/Parser/Internal.hs
+++ b/src/Data/Aeson/Parser/Internal.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE NoImplicitPrelude #-}
 {-# LANGUAGE OverloadedStrings #-}
 #if __GLASGOW_HASKELL__ <= 800 && __GLASGOW_HASKELL__ >= 706
@@ -60,6 +61,7 @@
 import Data.Scientific (Scientific)
 import Data.Text (Text)
 import Data.Vector (Vector)
+import Data.Word (Word8)
 import qualified Data.Vector as Vector (empty, fromList, fromListN, reverse)
 import qualified Data.Attoparsec.ByteString as A
 import qualified Data.Attoparsec.Lazy as L
@@ -77,22 +79,79 @@
 -- >>> :set -XOverloadedStrings
 -- >>> import Data.Aeson.Types
 
-#define BACKSLASH 92
-#define CLOSE_CURLY 125
-#define CLOSE_SQUARE 93
-#define COMMA 44
-#define DOUBLE_QUOTE 34
-#define OPEN_CURLY 123
-#define OPEN_SQUARE 91
-#define C_0 48
-#define C_9 57
-#define C_A 65
-#define C_F 70
-#define C_a 97
-#define C_f 102
-#define C_n 110
-#define C_t 116
+-------------------------------------------------------------------------------
+-- Word8 ASCII codes as patterns
+-------------------------------------------------------------------------------
 
+-- GHC-8.0 doesn't support giving multiple pattern synonyms type signature at once
+
+-- spaces
+pattern W8_SPACE :: Word8
+pattern W8_NL    :: Word8
+pattern W8_CR    :: Word8
+pattern W8_TAB   :: Word8
+
+pattern W8_SPACE = 0x20
+pattern W8_NL    = 0x0a
+pattern W8_CR    = 0x0d
+pattern W8_TAB   = 0x09
+
+-- punctuation
+pattern W8_BACKSLASH    :: Word8
+pattern W8_DOUBLE_QUOTE :: Word8
+pattern W8_DOT          :: Word8
+pattern W8_COMMA        :: Word8
+
+pattern W8_BACKSLASH    = 92
+pattern W8_COMMA        = 44
+pattern W8_DOT          = 46
+pattern W8_DOUBLE_QUOTE = 34
+
+-- parentheses
+pattern W8_CLOSE_CURLY  :: Word8
+pattern W8_CLOSE_SQUARE :: Word8
+pattern W8_OPEN_SQUARE  :: Word8
+pattern W8_OPEN_CURLY   :: Word8
+
+pattern W8_OPEN_CURLY   = 123
+pattern W8_OPEN_SQUARE  = 91
+pattern W8_CLOSE_CURLY  = 125
+pattern W8_CLOSE_SQUARE = 93
+
+-- operators
+pattern W8_MINUS :: Word8
+pattern W8_PLUS  :: Word8
+
+pattern W8_PLUS  = 43
+pattern W8_MINUS = 45
+
+-- digits
+pattern W8_0 :: Word8
+pattern W8_9 :: Word8
+
+pattern W8_0 = 48
+pattern W8_9 = 57
+
+-- lower case
+pattern W8_e :: Word8
+pattern W8_f :: Word8
+pattern W8_n :: Word8
+pattern W8_t :: Word8
+
+pattern W8_e = 101
+pattern W8_f = 102
+pattern W8_n = 110
+pattern W8_t = 116
+
+-- upper case
+pattern W8_E :: Word8
+pattern W8_E = 69
+
+
+-------------------------------------------------------------------------------
+-- Parsers
+-------------------------------------------------------------------------------
+
 -- | Parse any JSON value.
 --
 -- The conversion of a parsed value to a Haskell value is deferred
@@ -151,7 +210,7 @@
 objectValues mkObject str val = do
   skipSpace
   w <- A.peekWord8'
-  if w == CLOSE_CURLY
+  if w == W8_CLOSE_CURLY
     then A.anyWord8 >> return KM.empty
     else loop []
  where
@@ -162,9 +221,9 @@
   loop acc = do
     k <- (str A.<?> "object key") <* skipSpace <* (char ':' A.<?> "':'")
     v <- (val A.<?> "object value") <* skipSpace
-    ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_CURLY) A.<?> "',' or '}'"
+    ch <- A.satisfy (\w -> w == W8_COMMA || w == W8_CLOSE_CURLY) A.<?> "',' or '}'"
     let acc' = (k, v) : acc
-    if ch == COMMA
+    if ch == W8_COMMA
       then skipSpace >> loop acc'
       else case mkObject acc' of
         Left err -> fail err
@@ -185,14 +244,14 @@
 arrayValues val = do
   skipSpace
   w <- A.peekWord8'
-  if w == CLOSE_SQUARE
+  if w == W8_CLOSE_SQUARE
     then A.anyWord8 >> return Vector.empty
     else loop [] 1
   where
     loop acc !len = do
       v <- (val A.<?> "json list value") <* skipSpace
-      ch <- A.satisfy (\w -> w == COMMA || w == CLOSE_SQUARE) A.<?> "',' or ']'"
-      if ch == COMMA
+      ch <- A.satisfy (\w -> w == W8_COMMA || w == W8_CLOSE_SQUARE) A.<?> "',' or ']'"
+      if ch == W8_COMMA
         then skipSpace >> loop (v:acc) (len+1)
         else return (Vector.reverse (Vector.fromListN len (v:acc)))
 {-# INLINE arrayValues #-}
@@ -239,15 +298,15 @@
   skipSpace
   w <- A.peekWord8'
   case w of
-    DOUBLE_QUOTE  -> A.anyWord8 *> (String <$> jstring_)
-    OPEN_CURLY    -> A.anyWord8 *> object_ mkObject value_
-    OPEN_SQUARE   -> A.anyWord8 *> array_ value_
-    C_f           -> string "false" $> Bool False
-    C_t           -> string "true" $> Bool True
-    C_n           -> string "null" $> Null
-    _              | w >= 48 && w <= 57 || w == 45
-                  -> Number <$> scientific
-      | otherwise -> fail "not a valid json value"
+    W8_DOUBLE_QUOTE  -> A.anyWord8 *> (String <$> jstring_)
+    W8_OPEN_CURLY    -> A.anyWord8 *> object_ mkObject value_
+    W8_OPEN_SQUARE   -> A.anyWord8 *> array_ value_
+    W8_f             -> string "false" $> Bool False
+    W8_t             -> string "true" $> Bool True
+    W8_n             -> string "null" $> Null
+    _                 | w >= W8_0 && w <= W8_9 || w == W8_MINUS
+                     -> Number <$> scientific
+      | otherwise    -> fail "not a valid json value"
 {-# INLINE jsonWith #-}
 
 -- | Variant of 'json' which keeps only the last occurence of every key.
@@ -291,19 +350,19 @@
   skipSpace
   w <- A.peekWord8'
   case w of
-    DOUBLE_QUOTE  -> do
-                     !s <- A.anyWord8 *> jstring_
-                     return (String s)
-    OPEN_CURLY    -> A.anyWord8 *> object_' mkObject value_
-    OPEN_SQUARE   -> A.anyWord8 *> array_' value_
-    C_f           -> string "false" $> Bool False
-    C_t           -> string "true" $> Bool True
-    C_n           -> string "null" $> Null
-    _              | w >= 48 && w <= 57 || w == 45
-                  -> do
-                     !n <- scientific
-                     return (Number n)
-      | otherwise -> fail "not a valid json value"
+    W8_DOUBLE_QUOTE  -> do
+                       !s <- A.anyWord8 *> jstring_
+                       return (String s)
+    W8_OPEN_CURLY    -> A.anyWord8 *> object_' mkObject value_
+    W8_OPEN_SQUARE   -> A.anyWord8 *> array_' value_
+    W8_f             -> string "false" $> Bool False
+    W8_t             -> string "true" $> Bool True
+    W8_n             -> string "null" $> Null
+    _                 | w >= W8_0 && w <= W8_9 || w == W8_MINUS
+                     -> do
+                       !n <- scientific
+                       return (Number n)
+                      | otherwise -> fail "not a valid json value"
 {-# INLINE jsonWith' #-}
 
 -- | Variant of 'json'' which keeps only the last occurence of every key.
@@ -321,7 +380,7 @@
 
 -- | Parse a quoted JSON string.
 jstring :: Parser Text
-jstring = A.word8 DOUBLE_QUOTE *> jstring_
+jstring = A.word8 W8_DOUBLE_QUOTE *> jstring_
 
 -- | Parse a JSON Key
 key :: Parser Key
@@ -331,16 +390,13 @@
 jstring_ :: Parser Text
 {-# INLINE jstring_ #-}
 jstring_ = do
-  -- not sure whether >= or bit hackery is faster
-  -- perfectly, we shouldn't care, it's compiler job.
-  s <- A.takeWhile (\w -> w /= DOUBLE_QUOTE && w /= BACKSLASH && w >= 0x20 && w < 0x80)
-  let txt = unsafeDecodeASCII s
+  s <- A.takeWhile (\w -> w /= W8_DOUBLE_QUOTE && w /= W8_BACKSLASH && w >= 0x20 && w < 0x80)
   mw <- A.peekWord8
   case mw of
-    Nothing           -> fail "string without end"
-    Just DOUBLE_QUOTE -> A.anyWord8 $> txt
-    Just w | w < 0x20 -> fail "unescaped control character"
-    _                 -> jstringSlow s
+    Nothing              -> fail "string without end"
+    Just W8_DOUBLE_QUOTE -> A.anyWord8 $> unsafeDecodeASCII s
+    Just w | w < 0x20    -> fail "unescaped control character"
+    _                    -> jstringSlow s
 
 jstringSlow :: B.ByteString -> Parser Text
 {-# INLINE jstringSlow #-}
@@ -350,13 +406,12 @@
     Right r  -> return r
     Left err -> fail $ show err
  where
-    startState              = False
+    startState                = False
     go a c
-      | a                  = Just False
-      | c == DOUBLE_QUOTE  = Nothing
-      | otherwise = let a' = c == backslash
+      | a                     = Just False
+      | c == W8_DOUBLE_QUOTE  = Nothing
+      | otherwise = let a' = c == W8_BACKSLASH
                     in Just a'
-      where backslash = BACKSLASH
 
 decodeWith :: Parser Value -> (Value -> Result a) -> L.ByteString -> Maybe a
 decodeWith p to s =
@@ -451,7 +506,7 @@
 -- | The only valid whitespace in a JSON document is space, newline,
 -- carriage return, and tab.
 skipSpace :: Parser ()
-skipSpace = A.skipWhile $ \w -> w == 0x20 || w == 0x0a || w == 0x0d || w == 0x09
+skipSpace = A.skipWhile $ \w -> w == W8_SPACE || w == W8_NL || w == W8_CR || w == W8_TAB
 {-# INLINE skipSpace #-}
 
 ------------------ Copy-pasted and adapted from attoparsec ------------------
@@ -461,40 +516,34 @@
 
 decimal0 :: Parser Integer
 decimal0 = do
-  let zero = 48
   digits <- A.takeWhile1 isDigit_w8
-  if B.length digits > 1 && B.unsafeHead digits == zero
+  if B.length digits > 1 && B.unsafeHead digits == W8_0
     then fail "leading zero"
     else return (bsToInteger digits)
 
 -- | Parse a JSON number.
 scientific :: Parser Scientific
 scientific = do
-  let minus = 45
-      plus  = 43
   sign <- A.peekWord8'
-  let !positive = sign == plus || sign /= minus
-  when (sign == plus || sign == minus) $
+  let !positive = not (sign == W8_MINUS)
+  when (sign == W8_PLUS || sign == W8_MINUS) $
     void A.anyWord8
 
   n <- decimal0
 
   let f fracDigits = SP (B.foldl' step n fracDigits)
                         (negate $ B.length fracDigits)
-      step a w = a * 10 + fromIntegral (w - 48)
+      step a w = a * 10 + fromIntegral (w - W8_0)
 
   dotty <- A.peekWord8
-  -- '.' -> ascii 46
   SP c e <- case dotty of
-              Just 46 -> A.anyWord8 *> (f <$> A.takeWhile1 isDigit_w8)
-              _       -> pure (SP n 0)
+              Just W8_DOT -> A.anyWord8 *> (f <$> A.takeWhile1 isDigit_w8)
+              _           -> pure (SP n 0)
 
   let !signedCoeff | positive  =  c
                    | otherwise = -c
 
-  let littleE = 101
-      bigE    = 69
-  (A.satisfy (\ex -> ex == littleE || ex == bigE) *>
+  (A.satisfy (\ex -> case ex of W8_e -> True; W8_E -> True; _ -> False) *>
       fmap (Sci.scientific signedCoeff . (e +)) (signed decimal)) <|>
     return (Sci.scientific signedCoeff    e)
 {-# INLINE scientific #-}
@@ -503,14 +552,14 @@
 
 bsToInteger :: B.ByteString -> Integer
 bsToInteger bs
-    | l > 40    = valInteger 10 l [ fromIntegral (w - 48) | w <- B.unpack bs ]
+    | l > 40    = valInteger 10 l [ fromIntegral (w - W8_0) | w <- B.unpack bs ]
     | otherwise = bsToIntegerSimple bs
   where
     l = B.length bs
 
 bsToIntegerSimple :: B.ByteString -> Integer
 bsToIntegerSimple = B.foldl' step 0 where
-  step a b = a * 10 + fromIntegral (b - 48) -- 48 = '0'
+  step a b = a * 10 + fromIntegral (b - W8_0)
 
 -- A sub-quadratic algorithm for Integer. Pairs of adjacent radix b
 -- digits are combined into a single radix b^2 digit. This process is
diff --git a/tests/JSONTestSuite.hs b/tests/JSONTestSuite.hs
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite.hs
@@ -0,0 +1,80 @@
+module JSONTestSuite (tests) where
+
+import Test.Tasty (TestTree, testGroup)
+import Data.Either.Compat (isLeft, isRight)
+import Test.Tasty.HUnit ( testCase, assertBool )
+import System.Directory (getDirectoryContents)
+import System.FilePath ((</>), takeExtension, takeFileName)
+import Data.List (sort)
+import Control.Monad (forM)
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.HashSet as HashSet
+
+import Data.Aeson
+
+jsonTestSuiteTest :: FilePath -> TestTree
+jsonTestSuiteTest path = testCase fileName $ do
+    payload <- L.readFile path
+    let result = eitherDecode payload :: Either String Value
+    assertBool (show result) $ case take 2 fileName of
+      "n_"                                                -> isLeft result
+      "y_"                                                -> isRight result
+      "i_" | fileName `HashSet.member` ignore_accepted    -> isRight result
+           | otherwise                                    -> isLeft result
+      _    | fileName `HashSet.member` transform_rejected -> isLeft result
+           | otherwise                                    -> isRight result -- test_transform tests have inconsistent names
+  where
+    fileName = takeFileName path
+
+-- Build a collection of tests based on the current contents of the
+-- JSONTestSuite test directories.
+
+tests :: IO TestTree
+tests = do
+  let suitePath = "tests/JSONTestSuite"
+  let suites = ["test_parsing", "test_transform"]
+  testPaths <- fmap (sort . concat) . forM suites $ \suite -> do
+    let dir = suitePath </> suite
+    entries <- getDirectoryContents dir
+    let ok name = takeExtension name == ".json"
+    return . map (dir </>) . filter ok $ entries
+  return $ testGroup "JSONTestSuite" $ map jsonTestSuiteTest testPaths
+
+-- The set expected-to-be-failing JSONTestSuite tests.
+-- Not all of these failures are genuine bugs.
+-- Of those that are bugs, not all are worth fixing.
+
+-- | The @i@ cases we can ignore. We don't.
+--
+-- @i_@ - parsers are free to accept or reject content
+--
+-- We specify which @i_@ case we accept, so we can catch changes even in unspecified behavior.
+-- (There is less case we accept)
+ignore_accepted :: HashSet.HashSet FilePath
+ignore_accepted = HashSet.fromList
+    [ "i_number_double_huge_neg_exp.json"
+    , "i_number_huge_exp.json"
+    , "i_number_neg_int_huge_exp.json"
+    , "i_number_pos_double_huge_exp.json"
+    , "i_number_real_neg_overflow.json"
+    , "i_number_real_pos_overflow.json"
+    , "i_number_real_underflow.json"
+    , "i_number_too_big_neg_int.json"
+    , "i_number_too_big_pos_int.json"
+    , "i_number_very_big_negative_int.json"
+    , "i_structure_500_nested_arrays.json"
+    ]
+
+-- | Transform folder contain weird structures and characters that parsers may understand differently.
+--
+-- We don't even try to understand some.
+transform_rejected :: HashSet.HashSet FilePath
+transform_rejected = HashSet.fromList
+    [ "string_1_escaped_invalid_codepoint.json"
+    , "string_1_invalid_codepoint.json"
+    , "string_2_escaped_invalid_codepoints.json"
+    , "string_2_invalid_codepoints.json"
+    , "string_3_escaped_invalid_codepoints.json"
+    , "string_3_invalid_codepoints.json"
+    ]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_double_huge_neg_exp.json b/tests/JSONTestSuite/test_parsing/i_number_double_huge_neg_exp.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_double_huge_neg_exp.json
@@ -0,0 +1,1 @@
+[123.456e-789]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_huge_exp.json b/tests/JSONTestSuite/test_parsing/i_number_huge_exp.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_huge_exp.json
@@ -0,0 +1,1 @@
+[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_neg_int_huge_exp.json b/tests/JSONTestSuite/test_parsing/i_number_neg_int_huge_exp.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_neg_int_huge_exp.json
@@ -0,0 +1,1 @@
+[-1e+9999]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_pos_double_huge_exp.json b/tests/JSONTestSuite/test_parsing/i_number_pos_double_huge_exp.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_pos_double_huge_exp.json
@@ -0,0 +1,1 @@
+[1.5e+9999]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_real_neg_overflow.json b/tests/JSONTestSuite/test_parsing/i_number_real_neg_overflow.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_real_neg_overflow.json
@@ -0,0 +1,1 @@
+[-123123e100000]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_real_pos_overflow.json b/tests/JSONTestSuite/test_parsing/i_number_real_pos_overflow.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_real_pos_overflow.json
@@ -0,0 +1,1 @@
+[123123e100000]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_real_underflow.json b/tests/JSONTestSuite/test_parsing/i_number_real_underflow.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_real_underflow.json
@@ -0,0 +1,1 @@
+[123e-10000000]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_too_big_neg_int.json b/tests/JSONTestSuite/test_parsing/i_number_too_big_neg_int.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_too_big_neg_int.json
@@ -0,0 +1,1 @@
+[-123123123123123123123123123123]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_too_big_pos_int.json b/tests/JSONTestSuite/test_parsing/i_number_too_big_pos_int.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_too_big_pos_int.json
@@ -0,0 +1,1 @@
+[100000000000000000000]
diff --git a/tests/JSONTestSuite/test_parsing/i_number_very_big_negative_int.json b/tests/JSONTestSuite/test_parsing/i_number_very_big_negative_int.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_number_very_big_negative_int.json
@@ -0,0 +1,1 @@
+[-237462374673276894279832749832423479823246327846]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_UTF8_surrogate_U+D800.json b/tests/JSONTestSuite/test_parsing/i_string_UTF8_surrogate_U+D800.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_string_UTF8_surrogate_U+D800.json
@@ -0,0 +1,1 @@
+["í "]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_invalid_utf-8.json b/tests/JSONTestSuite/test_parsing/i_string_invalid_utf-8.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_string_invalid_utf-8.json
@@ -0,0 +1,1 @@
+["ÿ"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_iso_latin_1.json b/tests/JSONTestSuite/test_parsing/i_string_iso_latin_1.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_string_iso_latin_1.json
@@ -0,0 +1,1 @@
+["é"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_lone_utf8_continuation_byte.json b/tests/JSONTestSuite/test_parsing/i_string_lone_utf8_continuation_byte.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_string_lone_utf8_continuation_byte.json
@@ -0,0 +1,1 @@
+[""]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_2_bytes.json b/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_2_bytes.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_2_bytes.json
@@ -0,0 +1,1 @@
+["À¯"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes.json b/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes.json
@@ -0,0 +1,1 @@
+["ü¿¿¿¿"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes_null.json b/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes_null.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes_null.json
@@ -0,0 +1,1 @@
+["ü"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.json b/tests/JSONTestSuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+10FFFE_nonchar.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["\uDBFF\uDFFE"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.json b/tests/JSONTestSuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+1FFFE_nonchar.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["\uD83F\uDFFE"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+FDD0_nonchar.json b/tests/JSONTestSuite/test_parsing/i_string_unicode_U+FDD0_nonchar.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+FDD0_nonchar.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["\uFDD0"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+FFFE_nonchar.json b/tests/JSONTestSuite/test_parsing/i_string_unicode_U+FFFE_nonchar.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/i_string_unicode_U+FFFE_nonchar.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["\uFFFE"]
diff --git a/tests/JSONTestSuite/test_parsing/i_string_utf16BE_no_BOM.json b/tests/JSONTestSuite/test_parsing/i_string_utf16BE_no_BOM.json
new file mode 100644
Binary files /dev/null and b/tests/JSONTestSuite/test_parsing/i_string_utf16BE_no_BOM.json differ
diff --git a/tests/JSONTestSuite/test_parsing/i_string_utf16LE_no_BOM.json b/tests/JSONTestSuite/test_parsing/i_string_utf16LE_no_BOM.json
new file mode 100644
Binary files /dev/null and b/tests/JSONTestSuite/test_parsing/i_string_utf16LE_no_BOM.json differ
diff --git a/tests/JSONTestSuite/test_parsing/n_multidigit_number_then_00.json b/tests/JSONTestSuite/test_parsing/n_multidigit_number_then_00.json
new file mode 100644
Binary files /dev/null and b/tests/JSONTestSuite/test_parsing/n_multidigit_number_then_00.json differ
diff --git a/tests/JSONTestSuite/test_parsing/n_number_then_00.json b/tests/JSONTestSuite/test_parsing/n_number_then_00.json
deleted file mode 100644
Binary files a/tests/JSONTestSuite/test_parsing/n_number_then_00.json and /dev/null differ
diff --git a/tests/JSONTestSuite/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json b/tests/JSONTestSuite/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json
@@ -0,0 +1,1 @@
+{"¹":"0",}
diff --git a/tests/JSONTestSuite/test_parsing/n_object_pi_in_key_and_trailing_comma.json b/tests/JSONTestSuite/test_parsing/n_object_pi_in_key_and_trailing_comma.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_object_pi_in_key_and_trailing_comma.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"¹":"0",}
diff --git a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u.json b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["\uD800\u"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1.json b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["\uD800\u1"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1x.json b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1x.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape u1x.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["\uD800\u1x"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u.json b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u.json
@@ -0,0 +1,1 @@
+["\uD800\u"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1.json b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1.json
@@ -0,0 +1,1 @@
+["\uD800\u1"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1x.json b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1x.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1x.json
@@ -0,0 +1,1 @@
+["\uD800\u1x"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_UTF8_surrogate_U+D800.json b/tests/JSONTestSuite/test_parsing/n_string_UTF8_surrogate_U+D800.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_UTF8_surrogate_U+D800.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["í "]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_invalid_utf-8.json b/tests/JSONTestSuite/test_parsing/n_string_invalid_utf-8.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_invalid_utf-8.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["ÿ"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_iso_latin_1.json b/tests/JSONTestSuite/test_parsing/n_string_iso_latin_1.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_iso_latin_1.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["é"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_lone_utf8_continuation_byte.json b/tests/JSONTestSuite/test_parsing/n_string_lone_utf8_continuation_byte.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_lone_utf8_continuation_byte.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[""]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_2_bytes.json b/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_2_bytes.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_2_bytes.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["À¯"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes.json b/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["ü¿¿¿¿"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes_null.json b/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes_null.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_string_overlong_sequence_6_bytes_null.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["ü"]
diff --git a/tests/JSONTestSuite/test_parsing/n_string_unescaped_crtl_char.json b/tests/JSONTestSuite/test_parsing/n_string_unescaped_crtl_char.json
deleted file mode 100644
Binary files a/tests/JSONTestSuite/test_parsing/n_string_unescaped_crtl_char.json and /dev/null differ
diff --git a/tests/JSONTestSuite/test_parsing/n_string_unescaped_ctrl_char.json b/tests/JSONTestSuite/test_parsing/n_string_unescaped_ctrl_char.json
new file mode 100644
Binary files /dev/null and b/tests/JSONTestSuite/test_parsing/n_string_unescaped_ctrl_char.json differ
diff --git a/tests/JSONTestSuite/test_parsing/n_structure_angle_bracket_null.json b/tests/JSONTestSuite/test_parsing/n_structure_angle_bracket_null.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/n_structure_angle_bracket_null.json
@@ -0,0 +1,1 @@
+[<null>]
diff --git a/tests/JSONTestSuite/test_parsing/n_structure_null.json b/tests/JSONTestSuite/test_parsing/n_structure_null.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_structure_null.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[<null>]
diff --git a/tests/JSONTestSuite/test_parsing/n_structure_single_eacute.json b/tests/JSONTestSuite/test_parsing/n_structure_single_eacute.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/n_structure_single_eacute.json
@@ -0,0 +1,1 @@
+é
diff --git a/tests/JSONTestSuite/test_parsing/n_structure_single_point.json b/tests/JSONTestSuite/test_parsing/n_structure_single_point.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/n_structure_single_point.json
+++ /dev/null
@@ -1,1 +0,0 @@
-é
diff --git a/tests/JSONTestSuite/test_parsing/y_number_double_huge_neg_exp.json b/tests/JSONTestSuite/test_parsing/y_number_double_huge_neg_exp.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_double_huge_neg_exp.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[123.456e-789]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_huge_exp.json b/tests/JSONTestSuite/test_parsing/y_number_huge_exp.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_huge_exp.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_neg_int_huge_exp.json b/tests/JSONTestSuite/test_parsing/y_number_neg_int_huge_exp.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_neg_int_huge_exp.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[-1e+9999]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_pos_double_huge_exp.json b/tests/JSONTestSuite/test_parsing/y_number_pos_double_huge_exp.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_pos_double_huge_exp.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[1.5e+9999]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_real_neg_overflow.json b/tests/JSONTestSuite/test_parsing/y_number_real_neg_overflow.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_real_neg_overflow.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[-123123e100000]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_real_pos_overflow.json b/tests/JSONTestSuite/test_parsing/y_number_real_pos_overflow.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_real_pos_overflow.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[123123e100000]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_real_underflow.json b/tests/JSONTestSuite/test_parsing/y_number_real_underflow.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_real_underflow.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[123e-10000000]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_too_big_neg_int.json b/tests/JSONTestSuite/test_parsing/y_number_too_big_neg_int.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_too_big_neg_int.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[-123123123123123123123123123123]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_too_big_pos_int.json b/tests/JSONTestSuite/test_parsing/y_number_too_big_pos_int.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_too_big_pos_int.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[100000000000000000000]
diff --git a/tests/JSONTestSuite/test_parsing/y_number_very_big_negative_int.json b/tests/JSONTestSuite/test_parsing/y_number_very_big_negative_int.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_number_very_big_negative_int.json
+++ /dev/null
@@ -1,1 +0,0 @@
-[-237462374673276894279832749832423479823246327846]
diff --git a/tests/JSONTestSuite/test_parsing/y_object_extreme_numbers.json b/tests/JSONTestSuite/test_parsing/y_object_extreme_numbers.json
--- a/tests/JSONTestSuite/test_parsing/y_object_extreme_numbers.json
+++ b/tests/JSONTestSuite/test_parsing/y_object_extreme_numbers.json
diff --git a/tests/JSONTestSuite/test_parsing/y_string_nbsp_uescaped.json b/tests/JSONTestSuite/test_parsing/y_string_nbsp_uescaped.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/y_string_nbsp_uescaped.json
@@ -0,0 +1,1 @@
+["new\u00A0line"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_newline_uescaped.json b/tests/JSONTestSuite/test_parsing/y_string_newline_uescaped.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_string_newline_uescaped.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["new\u00A0line"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json b/tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json
deleted file mode 100644
--- a/tests/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+1FFFF.json
+++ /dev/null
@@ -1,1 +0,0 @@
-["𛿿"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json b/tests/JSONTestSuite/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json
@@ -0,0 +1,1 @@
+["𛿿"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_uescaped_newline.json b/tests/JSONTestSuite/test_parsing/y_string_uescaped_newline.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/y_string_uescaped_newline.json
@@ -0,0 +1,1 @@
+["new\u000Aline"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_unicode_U+10FFFE_nonchar.json b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+10FFFE_nonchar.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+10FFFE_nonchar.json
@@ -0,0 +1,1 @@
+["\uDBFF\uDFFE"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_unicode_U+1FFFE_nonchar.json b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+1FFFE_nonchar.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+1FFFE_nonchar.json
@@ -0,0 +1,1 @@
+["\uD83F\uDFFE"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_unicode_U+FDD0_nonchar.json b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+FDD0_nonchar.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+FDD0_nonchar.json
@@ -0,0 +1,1 @@
+["\uFDD0"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_unicode_U+FFFE_nonchar.json b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+FFFE_nonchar.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_parsing/y_string_unicode_U+FFFE_nonchar.json
@@ -0,0 +1,1 @@
+["\uFFFE"]
diff --git a/tests/JSONTestSuite/test_parsing/y_string_utf16BE_no_BOM.json b/tests/JSONTestSuite/test_parsing/y_string_utf16BE_no_BOM.json
deleted file mode 100644
Binary files a/tests/JSONTestSuite/test_parsing/y_string_utf16BE_no_BOM.json and /dev/null differ
diff --git a/tests/JSONTestSuite/test_parsing/y_string_utf16LE_no_BOM.json b/tests/JSONTestSuite/test_parsing/y_string_utf16LE_no_BOM.json
deleted file mode 100644
Binary files a/tests/JSONTestSuite/test_parsing/y_string_utf16LE_no_BOM.json and /dev/null differ
diff --git a/tests/JSONTestSuite/test_transform/number_-9223372036854775808.json b/tests/JSONTestSuite/test_transform/number_-9223372036854775808.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_transform/number_-9223372036854775808.json
@@ -0,0 +1,1 @@
+[-9223372036854775808]
diff --git a/tests/JSONTestSuite/test_transform/number_-9223372036854775809.json b/tests/JSONTestSuite/test_transform/number_-9223372036854775809.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_transform/number_-9223372036854775809.json
@@ -0,0 +1,1 @@
+[-9223372036854775809]
diff --git a/tests/JSONTestSuite/test_transform/number_10000000000000000999.json b/tests/JSONTestSuite/test_transform/number_10000000000000000999.json
--- a/tests/JSONTestSuite/test_transform/number_10000000000000000999.json
+++ b/tests/JSONTestSuite/test_transform/number_10000000000000000999.json
diff --git a/tests/JSONTestSuite/test_transform/number_1e-999.json b/tests/JSONTestSuite/test_transform/number_1e-999.json
--- a/tests/JSONTestSuite/test_transform/number_1e-999.json
+++ b/tests/JSONTestSuite/test_transform/number_1e-999.json
diff --git a/tests/JSONTestSuite/test_transform/number_1e6.json b/tests/JSONTestSuite/test_transform/number_1e6.json
--- a/tests/JSONTestSuite/test_transform/number_1e6.json
+++ b/tests/JSONTestSuite/test_transform/number_1e6.json
diff --git a/tests/JSONTestSuite/test_transform/number_9223372036854775807.json b/tests/JSONTestSuite/test_transform/number_9223372036854775807.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_transform/number_9223372036854775807.json
@@ -0,0 +1,1 @@
+[9223372036854775807]
diff --git a/tests/JSONTestSuite/test_transform/number_9223372036854775808.json b/tests/JSONTestSuite/test_transform/number_9223372036854775808.json
new file mode 100644
--- /dev/null
+++ b/tests/JSONTestSuite/test_transform/number_9223372036854775808.json
@@ -0,0 +1,1 @@
+[9223372036854775808]
diff --git a/tests/Regression/Issue967.hs b/tests/Regression/Issue967.hs
new file mode 100644
--- /dev/null
+++ b/tests/Regression/Issue967.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE Strict #-}
+{-# LANGUAGE TemplateHaskell #-}
+-- {-# OPTIONS_GHC -ddump-splices #-}
+-- {-# OPTIONS_GHC -ddump-simpl -ddump-to-file #-}
+module Regression.Issue967 (issue967) where
+
+import Test.Tasty (TestTree)
+import Test.Tasty.HUnit (testCase, assertEqual)
+
+import qualified Data.Text.Lazy as LT
+import qualified Data.Text.Lazy.Encoding as LTE
+
+import Data.Aeson
+import Data.Aeson.TH
+
+data DataA = DataA
+  { val1 :: Int,
+    val2 :: Int
+  }
+  deriving (Eq, Show)
+
+-------------------------------------------------------------------------------
+-- Instances
+-------------------------------------------------------------------------------
+
+$(deriveJSON defaultOptions ''DataA)
+
+-------------------------------------------------------------------------------
+-- Test
+-------------------------------------------------------------------------------
+
+issue967 :: TestTree
+issue967 = testCase "issue967" $ do
+  let ev = DataA 1 2
+      encoding = encode ev
+      parsedEv = decode encoding :: Maybe DataA
+
+  assertEqual (LT.unpack $ LTE.decodeUtf8 encoding) (Just ev) parsedEv
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -8,9 +8,11 @@
 import qualified DataFamilies.Properties as DF
 import qualified Properties
 import qualified UnitTests
+import qualified JSONTestSuite
 
 main :: IO ()
 main = do
     ioTests <- UnitTests.ioTests
-    let allTests = DF.tests : Properties.tests : UnitTests.tests : ioTests
+    jsTests <- JSONTestSuite.tests
+    let allTests = DF.tests : Properties.tests : UnitTests.tests : jsTests : ioTests
     defaultMain (testGroup "tests" allTests)
diff --git a/tests/UnitTests.hs b/tests/UnitTests.hs
--- a/tests/UnitTests.hs
+++ b/tests/UnitTests.hs
@@ -49,10 +49,9 @@
 import qualified Data.Aeson.KeyMap as KM
 import Data.Attoparsec.ByteString (Parser, parseOnly)
 import Data.Char (toUpper, GeneralCategory(Control,Surrogate), generalCategory)
-import Data.Either.Compat (isLeft, isRight)
 import Data.Hashable (hash)
 import Data.HashMap.Strict (HashMap)
-import Data.List (sort, isSuffixOf)
+import Data.List (isSuffixOf)
 import Data.Maybe (fromMaybe)
 import Data.Scientific (Scientific, scientific)
 import Data.Tagged (Tagged(..))
@@ -63,16 +62,13 @@
 import GHC.Generics.Generically (Generically (..))
 import Instances ()
 import Numeric.Natural (Natural)
-import System.Directory (getDirectoryContents)
-import System.FilePath ((</>), takeExtension, takeFileName)
 import Test.Tasty (TestTree, testGroup)
-import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, assertEqual, testCase, (@?=))
+import Test.Tasty.HUnit (Assertion, assertFailure, assertEqual, testCase, (@?=))
 import Text.Printf (printf)
 import UnitTests.NullaryConstructors (nullaryConstructors)
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Base16.Lazy as LBase16
 import qualified Data.ByteString.Lazy.Char8 as L
-import qualified Data.HashSet as HashSet
 import qualified Data.Text.Lazy as LT
 import qualified Data.Text.Lazy.Builder as TLB
 import qualified Data.Text.Lazy.Encoding as LT
@@ -81,6 +77,7 @@
 import qualified ErrorMessages
 import qualified SerializationFormatSpec
 import qualified Data.Map as Map -- Lazy!
+import Regression.Issue967
 
 roundTripCamel :: String -> Assertion
 roundTripCamel name = assertEqual "" name (camelFrom '_' $ camelTo '_' name)
@@ -419,73 +416,8 @@
       Surrogate -> False
       _ -> True
 
--- JSONTestSuite
 
-jsonTestSuiteTest :: FilePath -> TestTree
-jsonTestSuiteTest path = testCase fileName $ do
-    payload <- L.readFile path
-    let result = eitherDecode payload :: Either String Value
-    assertBool fileName $ case take 2 fileName of
-      "i_" -> isRight result
-      "n_" -> isLeft result
-      "y_" -> isRight result
-      _    -> isRight result -- test_transform tests have inconsistent names
-  where
-    fileName = takeFileName path
 
--- Build a collection of tests based on the current contents of the
--- JSONTestSuite test directories.
-
-jsonTestSuite :: IO TestTree
-jsonTestSuite = do
-  let suitePath = "tests/JSONTestSuite"
-  let suites = ["test_parsing", "test_transform"]
-  testPaths <- fmap (sort . concat) . forM suites $ \suite -> do
-    let dir = suitePath </> suite
-    entries <- getDirectoryContents dir
-    let ok name = takeExtension name == ".json" &&
-                  not (name `HashSet.member` blacklist)
-    return . map (dir </>) . filter ok $ entries
-  return $ testGroup "JSONTestSuite" $ map jsonTestSuiteTest testPaths
-
--- The set expected-to-be-failing JSONTestSuite tests.
--- Not all of these failures are genuine bugs.
--- Of those that are bugs, not all are worth fixing.
-
-blacklist :: HashSet.HashSet String
--- blacklist = HashSet.empty
-blacklist = _blacklist
-
-_blacklist :: HashSet.HashSet String
-_blacklist = HashSet.fromList [
-    "i_object_key_lone_2nd_surrogate.json"
-  , "i_string_1st_surrogate_but_2nd_missing.json"
-  , "i_string_1st_valid_surrogate_2nd_invalid.json"
-  , "i_string_UTF-16LE_with_BOM.json"
-  , "i_string_UTF-16_invalid_lonely_surrogate.json"
-  , "i_string_UTF-16_invalid_surrogate.json"
-  , "i_string_UTF-8_invalid_sequence.json"
-  , "i_string_incomplete_surrogate_and_escape_valid.json"
-  , "i_string_incomplete_surrogate_pair.json"
-  , "i_string_incomplete_surrogates_escape_valid.json"
-  , "i_string_invalid_lonely_surrogate.json"
-  , "i_string_invalid_surrogate.json"
-  , "i_string_inverted_surrogates_U+1D11E.json"
-  , "i_string_lone_second_surrogate.json"
-  , "i_string_not_in_unicode_range.json"
-  , "i_string_truncated-utf-8.json"
-  , "i_structure_UTF-8_BOM_empty_object.json"
-  , "string_1_escaped_invalid_codepoint.json"
-  , "string_1_invalid_codepoint.json"
-  , "string_1_invalid_codepoints.json"
-  , "string_2_escaped_invalid_codepoints.json"
-  , "string_2_invalid_codepoints.json"
-  , "string_3_escaped_invalid_codepoints.json"
-  , "string_3_invalid_codepoints.json"
-  , "y_string_utf16BE_no_BOM.json"
-  , "y_string_utf16LE_no_BOM.json"
-  ]
-
 -- A regression test for: https://github.com/bos/aeson/pull/455
 data Foo a = FooNil | FooCons (Foo Int)
 deriveToJSON  defaultOptions ''Foo
@@ -838,8 +770,7 @@
 ioTests :: IO [TestTree]
 ioTests = do
   enc <- encoderComparisonTests
-  js <- jsonTestSuite
-  return [enc, js]
+  return [enc]
 
 tests :: TestTree
 tests = testGroup "unit" [
@@ -894,4 +825,10 @@
       assertEqual "" (object ["foo" .= True]) [aesonQQ| {"foo": true } |]
     ]
   , monadFixTests
+  , issue967
+  , testCase "KeyMap.insertWith" $ do
+      KM.insertWith (-)        "a" 2 (KM.fromList [("a", 1)]) @?= KM.fromList [("a",1 :: Int)]
+      KM.insertWith (flip (-)) "a" 2 (KM.fromList [("a", 1)]) @?= KM.fromList [("a",-1 :: Int)]
+      KM.insertWith (-)        "b" 2 (KM.fromList [("a", 1)]) @?= KM.fromList [("a",1),("b",2 :: Int)]
+      KM.insertWith (-)        "b" 2 KM.empty                 @?= KM.fromList [("b",2 :: Int)]
   ]
