diff --git a/Data/Aeson/Encode.hs b/Data/Aeson/Encode.hs
--- a/Data/Aeson/Encode.hs
+++ b/Data/Aeson/Encode.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE BangPatterns, OverloadedStrings #-}
+{-# LANGUAGE CPP, BangPatterns, OverloadedStrings #-}
 
 -- |
 -- Module:      Data.Aeson.Encode
@@ -14,50 +14,74 @@
 -- Most frequently, you'll probably want to encode straight to UTF-8
 -- (the standard JSON encoding) using 'encode'.
 --
--- You can convert a 'Builder' (as returned by 'fromValue') to a
--- string using e.g. 'toLazyText'.
-
+-- You can use the conversions to 'Builder's when embedding JSON messages as
+-- parts of a protocol.
 module Data.Aeson.Encode
-    (
-      fromValue
-    , encode
+    ( encode
+
+#if MIN_VERSION_bytestring(0,10,4)
+    -- * Encoding to Builders
+    , encodeToByteStringBuilder
+    , encodeToTextBuilder
+#else
+    -- * Encoding to Text Builders
+    , encodeToTextBuilder
+#endif
+
+    -- * Deprecated
+    , fromValue
     ) where
 
-import Data.Aeson.Types (ToJSON(..), Value(..))
-import Data.Attoparsec.Number (Number(..))
+import Data.Aeson.Types (Value(..))
 import Data.Monoid (mappend)
+import Data.Scientific (Scientific, coefficient, base10Exponent, scientificBuilder)
 import Data.Text.Lazy.Builder
 import Data.Text.Lazy.Builder.Int (decimal)
-import Data.Text.Lazy.Builder.RealFloat (realFloat)
-import Data.Text.Lazy.Encoding (encodeUtf8)
 import Numeric (showHex)
-import qualified Data.ByteString.Lazy as L
 import qualified Data.HashMap.Strict as H
 import qualified Data.Text as T
 import qualified Data.Vector as V
 
--- | Encode a JSON value to a 'Builder'.  You can convert this to a
--- string using e.g. 'toLazyText', or encode straight to UTF-8 (the
--- standard JSON encoding) using 'encode'.
+#if MIN_VERSION_bytestring(0,10,4)
+import Data.Aeson.Encode.ByteString (encode, encodeToByteStringBuilder)
+#else
+import Data.Aeson.Types (ToJSON(toJSON))
+import qualified Data.ByteString.Lazy    as BL
+import qualified Data.Text.Lazy.Builder  as TLB
+import qualified Data.Text.Lazy.Encoding as TLE
+
+-- | Encode a JSON 'Value' as a UTF-8 encoded 'BL.ByteString'.
+encode :: ToJSON a => a -> BL.ByteString
+encode = TLE.encodeUtf8 . TLB.toLazyText . encodeToTextBuilder . toJSON
+#endif
+
+-- | Encode a JSON 'Value' to a 'Builder', which can be embedded efficiently
+-- in a text-based protocol.
+encodeToTextBuilder :: Value -> Builder
+encodeToTextBuilder =
+    go
+  where
+    go Null       = {-# SCC "go/Null" #-} "null"
+    go (Bool b)   = {-# SCC "go/Bool" #-} if b then "true" else "false"
+    go (Number s) = {-# SCC "go/Number" #-} fromScientific s
+    go (String s) = {-# SCC "go/String" #-} string s
+    go (Array v)
+        | V.null v = {-# SCC "go/Array" #-} "[]"
+        | otherwise = {-# SCC "go/Array" #-}
+                      singleton '[' <>
+                      go (V.unsafeHead v) <>
+                      V.foldr f (singleton ']') (V.unsafeTail v)
+      where f a z = singleton ',' <> go a <> z
+    go (Object m) = {-# SCC "go/Object" #-}
+        case H.toList m of
+          (x:xs) -> singleton '{' <> one x <> foldr f (singleton '}') xs
+          _      -> "{}"
+      where f a z     = singleton ',' <> one a <> z
+            one (k,v) = string k <> singleton ':' <> go v
+
+{-# DEPRECATED fromValue "Use 'encodeToTextBuilder' instead" #-}
 fromValue :: Value -> Builder
-fromValue Null = {-# SCC "fromValue/Null" #-} "null"
-fromValue (Bool b) = {-# SCC "fromValue/Bool" #-}
-                     if b then "true" else "false"
-fromValue (Number n) = {-# SCC "fromValue/Number" #-} fromNumber n
-fromValue (String s) = {-# SCC "fromValue/String" #-} string s
-fromValue (Array v)
-    | V.null v = {-# SCC "fromValue/Array" #-} "[]"
-    | otherwise = {-# SCC "fromValue/Array" #-}
-                  singleton '[' <>
-                  fromValue (V.unsafeHead v) <>
-                  V.foldr f (singleton ']') (V.unsafeTail v)
-  where f a z = singleton ',' <> fromValue a <> z
-fromValue (Object m) = {-# SCC "fromValue/Object" #-}
-    case H.toList m of
-      (x:xs) -> singleton '{' <> one x <> foldr f (singleton '}') xs
-      _      -> "{}"
-  where f a z     = singleton ',' <> one a <> z
-        one (k,v) = string k <> singleton ':' <> fromValue v
+fromValue = encodeToTextBuilder
 
 string :: T.Text -> Builder
 string s = {-# SCC "string" #-} singleton '"' <> quote s <> singleton '"'
@@ -87,17 +111,12 @@
         | otherwise  = singleton c
         where h = showHex (fromEnum c) ""
 
-fromNumber :: Number -> Builder
-fromNumber (I i) = decimal i
-fromNumber (D d)
-    | isNaN d || isInfinite d = "null"
-    | otherwise               = realFloat d
-
--- | Efficiently serialize a JSON value as a lazy 'L.ByteString'.
-encode :: ToJSON a => a -> L.ByteString
-encode = {-# SCC "encode" #-} encodeUtf8 . toLazyText . fromValue .
-         {-# SCC "toJSON" #-} toJSON
-{-# INLINE encode #-}
+fromScientific :: Scientific -> Builder
+fromScientific s
+    | e < 0     = scientificBuilder s
+    | otherwise = decimal (coefficient s * 10 ^ e)
+  where
+    e = base10Exponent s
 
 (<>) :: Builder -> Builder -> Builder
 (<>) = mappend
diff --git a/Data/Aeson/Encode/ByteString.hs b/Data/Aeson/Encode/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/Data/Aeson/Encode/ByteString.hs
@@ -0,0 +1,116 @@
+{-# LANGUAGE BangPatterns, OverloadedStrings #-}
+
+-- |
+-- Module:      Data.Aeson.EncodeUtf8
+-- Copyright:   (c) 2011 MailRank, Inc.
+--              (c) 2013 Simon Meier <iridcode@gmail.com>
+-- License:     Apache
+-- Maintainer:  Bryan O'Sullivan <bos@serpentine.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Efficiently serialize a JSON value using the UTF-8 encoding.
+
+module Data.Aeson.Encode.ByteString
+    ( encode
+    , encodeToByteStringBuilder
+    ) where
+
+import Prelude hiding (null)
+import Data.Aeson.Types (ToJSON(..), Value(..))
+import Data.Char (ord)
+import Data.Scientific (Scientific, coefficient, base10Exponent, formatScientific, FPFormat(Generic))
+import Data.Word (Word8)
+import Data.Monoid (mappend)
+import           Data.ByteString.Builder      as B
+import           Data.ByteString.Builder.Prim as BP
+import qualified Data.ByteString.Lazy as L
+import qualified Data.HashMap.Strict as HMS
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as TE
+import qualified Data.Vector as V
+
+(<>) :: Builder -> Builder -> Builder
+(<>) = mappend
+{-# INLINE (<>) #-}
+infixr 6 <>
+
+-- | Efficiently serialize a JSON value as a lazy 'L.ByteString'.
+encode :: ToJSON a => a -> L.ByteString
+encode = B.toLazyByteString . encodeToByteStringBuilder . toJSON
+
+-- | Encode a JSON value to a ByteString 'B.Builder'. Use this function if you
+-- must prepend or append further bytes to the encoded JSON value.
+encodeToByteStringBuilder :: Value -> Builder
+encodeToByteStringBuilder Null       = null
+encodeToByteStringBuilder (Bool b)   = bool b
+encodeToByteStringBuilder (Number n) = number n
+encodeToByteStringBuilder (String s) = string s
+encodeToByteStringBuilder (Array v)  = array v
+encodeToByteStringBuilder (Object m) = object m
+
+null :: Builder
+null = BP.primBounded (ascii4 ('n',('u',('l','l')))) ()
+
+bool :: Bool -> Builder
+bool = BP.primBounded (BP.condB id (ascii4 ('t',('r',('u','e'))))
+                                   (ascii5 ('f',('a',('l',('s','e'))))))
+
+array :: V.Vector Value -> Builder
+array v
+  | V.null v  = B.char8 '[' <> B.char8 ']'
+  | otherwise = B.char8 '[' <>
+                encodeToByteStringBuilder (V.unsafeHead v) <>
+                V.foldr withComma (B.char8 ']') (V.unsafeTail v)
+  where
+    withComma a z = B.char8 ',' <> encodeToByteStringBuilder a <> z
+
+object :: HMS.HashMap T.Text Value -> Builder
+object m = case HMS.toList m of
+    (x:xs) -> B.char8 '{' <> one x <> foldr withComma (B.char8 '}') xs
+    _      -> B.char8 '{' <> B.char8 '}'
+  where
+    withComma a z = B.char8 ',' <> one a <> z
+    one (k,v)     = string k <> B.char8 ':' <> encodeToByteStringBuilder v
+
+string :: T.Text -> B.Builder
+string t =
+    B.char8 '"' <> TE.encodeUtf8BuilderEscaped escapeAscii t <> B.char8 '"'
+  where
+    escapeAscii :: BP.BoundedPrim Word8
+    escapeAscii =
+        BP.condB (== c2w '\\'  ) (ascii2 ('\\','\\')) $
+        BP.condB (== c2w '\"'  ) (ascii2 ('\\','"' )) $
+        BP.condB (>= c2w '\x20') (BP.liftFixedToBounded BP.word8) $
+        BP.condB (== c2w '\n'  ) (ascii2 ('\\','n' )) $
+        BP.condB (== c2w '\r'  ) (ascii2 ('\\','r' )) $
+        BP.condB (== c2w '\t'  ) (ascii2 ('\\','t' )) $
+        (BP.liftFixedToBounded hexEscape) -- fallback for chars < 0x20
+
+    c2w = fromIntegral . ord
+
+    hexEscape :: BP.FixedPrim Word8
+    hexEscape = (\c -> ('\\', ('u', fromIntegral c))) BP.>$<
+        BP.char8 BP.>*< BP.char8 BP.>*< BP.word16HexFixed
+
+number :: Scientific -> Builder
+number s
+    | e < 0     = B.string8 $ formatScientific Generic Nothing s
+    | otherwise = B.integerDec (coefficient s * 10 ^ e)
+  where
+    e = base10Exponent s
+
+
+{-# INLINE ascii2 #-}
+ascii2 :: (Char, Char) -> BP.BoundedPrim a
+ascii2 cs = BP.liftFixedToBounded $ (const cs) BP.>$< BP.char7 BP.>*< BP.char7
+
+{-# INLINE ascii4 #-}
+ascii4 :: (Char, (Char, (Char, Char))) -> BP.BoundedPrim a
+ascii4 cs = BP.liftFixedToBounded $ (const cs) >$<
+    BP.char7 BP.>*< BP.char7 BP.>*< BP.char7 BP.>*< BP.char7
+
+{-# INLINE ascii5 #-}
+ascii5 :: (Char, (Char, (Char, (Char, Char)))) -> BP.BoundedPrim a
+ascii5 cs = BP.liftFixedToBounded $ (const cs) >$<
+    BP.char7 BP.>*< BP.char7 BP.>*< BP.char7 BP.>*< BP.char7 BP.>*< BP.char7
diff --git a/Data/Aeson/Functions.hs b/Data/Aeson/Functions.hs
--- a/Data/Aeson/Functions.hs
+++ b/Data/Aeson/Functions.hs
@@ -12,17 +12,9 @@
     , hashMapKey
     , mapKeyVal
     , mapKey
-    -- * String conversions
-    , decode
-    , strict
-    , lazy
     ) where
 
 import Data.Hashable (Hashable)
-import Data.Text (Text)
-import Data.Text.Encoding (decodeUtf8, encodeUtf8)
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Lazy as L
 import qualified Data.HashMap.Strict as H
 import qualified Data.Map as M
 
@@ -48,15 +40,3 @@
 mapKey :: (Eq k2, Hashable k2) => (k1 -> k2) -> H.HashMap k1 v -> H.HashMap k2 v
 mapKey fk = mapKeyVal fk id
 {-# INLINE mapKey #-}
-
-strict :: L.ByteString -> Text
-strict = decode . B.concat . L.toChunks
-{-# INLINE strict #-}
-
-lazy :: Text -> L.ByteString
-lazy = L.fromChunks . (:[]) . encodeUtf8
-{-# INLINE lazy #-}
-
-decode :: B.ByteString -> Text
-decode = decodeUtf8
-{-# INLINE decode #-}
diff --git a/Data/Aeson/Generic.hs b/Data/Aeson/Generic.hs
--- a/Data/Aeson/Generic.hs
+++ b/Data/Aeson/Generic.hs
@@ -30,7 +30,7 @@
 import Control.Applicative ((<$>))
 import Control.Arrow (first)
 import Control.Monad.State.Strict
-import Data.Aeson.Functions hiding (decode)
+import Data.Aeson.Functions
 import Data.Aeson.Types hiding (FromJSON(..), ToJSON(..), fromJSON)
 import Data.Attoparsec.Number (Number)
 import Data.Generics
@@ -39,14 +39,11 @@
 import Data.IntSet (IntSet)
 import Data.Maybe (fromJust)
 import Data.Text (Text, pack, unpack)
-import Data.Text.Encoding (encodeUtf8)
 import Data.Time.Clock (UTCTime)
 import Data.Word (Word, Word8, Word16, Word32, Word64)
 import Data.Aeson.Parser.Internal (decodeWith, json, json')
 import qualified Data.Aeson.Encode as E
-import qualified Data.Aeson.Functions as F
 import qualified Data.Aeson.Types as T
-import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as L
 import qualified Data.HashMap.Strict as H
 import qualified Data.Map as Map
@@ -111,8 +108,6 @@
          `extQ` (T.toJSON :: T Text)
          `extQ` (T.toJSON :: T LT.Text)
          `extQ` (T.toJSON :: T String)
-         `extQ` (T.toJSON :: T B.ByteString)
-         `extQ` (T.toJSON :: T L.ByteString)
          `extQ` (T.toJSON :: T T.Value)
          `extQ` (T.toJSON :: T DotNetTime)
          `extQ` (T.toJSON :: T UTCTime)
@@ -129,8 +124,6 @@
       | tyrep == typeOf DT.empty = remap id
       | tyrep == typeOf LT.empty = remap LT.toStrict
       | tyrep == typeOf ""       = remap pack
-      | tyrep == typeOf B.empty  = remap F.decode
-      | tyrep == typeOf L.empty  = remap strict
       | otherwise = modError "toJSON" $
                              "cannot convert map keyed by type " ++ show tyrep
       where tyrep = typeOf . head . Map.keys $ m
@@ -140,8 +133,6 @@
       | tyrep == typeOf DT.empty = remap id
       | tyrep == typeOf LT.empty = remap LT.toStrict
       | tyrep == typeOf ""       = remap pack
-      | tyrep == typeOf B.empty  = remap F.decode
-      | tyrep == typeOf L.empty  = remap strict
       | otherwise = modError "toJSON" $
                              "cannot convert map keyed by type " ++ show tyrep
       where tyrep = typeOf . head . H.keys $ m
@@ -214,8 +205,6 @@
              `extR` (value :: F Text)
              `extR` (value :: F LT.Text)
              `extR` (value :: F String)
-             `extR` (value :: F B.ByteString)
-             `extR` (value :: F L.ByteString)
              `extR` (value :: F T.Value)
              `extR` (value :: F DotNetTime)
              `extR` (value :: F UTCTime)
@@ -239,8 +228,6 @@
         | tyrep == typeOf DT.empty = process id
         | tyrep == typeOf LT.empty = process LT.fromStrict
         | tyrep == typeOf ""       = process DT.unpack
-        | tyrep == typeOf B.empty  = process encodeUtf8
-        | tyrep == typeOf L.empty  = process lazy
         | otherwise = myFail
         where
           process f = maybe myFail return . cast =<< parseWith f
@@ -256,8 +243,6 @@
         | tyrep == typeOf DT.empty = process id
         | tyrep == typeOf LT.empty = process LT.fromStrict
         | tyrep == typeOf ""       = process DT.unpack
-        | tyrep == typeOf B.empty  = process encodeUtf8
-        | tyrep == typeOf L.empty  = process lazy
         | otherwise = myFail
       where
         process f = maybe myFail return . cast =<< parseWith f
diff --git a/Data/Aeson/Parser/Internal.hs b/Data/Aeson/Parser/Internal.hs
--- a/Data/Aeson/Parser/Internal.hs
+++ b/Data/Aeson/Parser/Internal.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE BangPatterns, OverloadedStrings #-}
+{-# LANGUAGE CPP, BangPatterns, OverloadedStrings #-}
 
 -- |
 -- Module:      Data.Aeson.Parser.Internal
@@ -28,28 +28,55 @@
     , eitherDecodeStrictWith
     ) where
 
-import Blaze.ByteString.Builder (fromByteString, toByteString)
+#if defined(USE_BLAZE_BUILDER)
+import Blaze.ByteString.Builder (Builder, fromByteString, toByteString)
 import Blaze.ByteString.Builder.Char.Utf8 (fromChar)
 import Blaze.ByteString.Builder.Word (fromWord8)
-import Control.Applicative as A
+#else
+#if MIN_VERSION_bytestring(0,10,2)
+import Data.ByteString.Builder
+#else
+import Data.ByteString.Lazy.Builder
+#endif
+  (Builder, byteString, toLazyByteString, charUtf8, word8)
+#endif
+
+import Control.Applicative ((*>), (<$>), (<*), liftA2, pure)
 import Data.Aeson.Types (Result(..), Value(..))
-import Data.Attoparsec.Char8 hiding (Result)
+import Data.Attoparsec.Char8 (Parser, char, endOfInput, rational,
+                              skipSpace, string)
 import Data.Bits ((.|.), shiftL)
-import Data.ByteString as B
+import Data.ByteString (ByteString)
 import Data.Char (chr)
 import Data.Monoid (mappend, mempty)
-import Data.Text as T
+import Data.Text (Text)
 import Data.Text.Encoding (decodeUtf8')
-import Data.Vector as Vector hiding ((++))
+import Data.Vector as Vector (Vector, fromList)
 import Data.Word (Word8)
 import qualified Data.Attoparsec as A
 import qualified Data.Attoparsec.Lazy as L
 import qualified Data.Attoparsec.Zepto as Z
-import qualified Data.ByteString.Char8 as B8
+import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as L
 import qualified Data.ByteString.Unsafe as B
 import qualified Data.HashMap.Strict as H
 
+#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
+
 -- | Parse a top-level JSON value.  This must be either an object or
 -- an array, per RFC 4627.
 --
@@ -71,8 +98,8 @@
 
 json_ :: Parser Value -> Parser Value -> Parser Value
 json_ obj ary = do
-  w <- skipSpace *> A.satisfy (\w -> w == 123 || w == 91)
-  if w == 123
+  w <- skipSpace *> A.satisfy (\w -> w == OPEN_CURLY || w == OPEN_SQUARE)
+  if w == OPEN_CURLY
     then obj
     else ary
 {-# INLINE json_ #-}
@@ -92,12 +119,8 @@
 objectValues :: Parser Text -> Parser Value -> Parser (H.HashMap Text Value)
 objectValues str val = do
   skipSpace
-  let pair = do
-        a <- str <* skipSpace
-        b <- char ':' *> skipSpace *> val
-        return (a,b)
-  vals <- ((pair <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char '}'
-  return (H.fromList vals)
+  let pair = liftA2 (,) (str <* skipSpace) (char ':' *> skipSpace *> val)
+  H.fromList <$> commaSeparated pair CLOSE_CURLY
 {-# INLINE objectValues #-}
 
 array_ :: Parser Value
@@ -108,11 +131,25 @@
   !vals <- arrayValues value'
   return (Array vals)
 
+commaSeparated :: Parser a -> Word8 -> Parser [a]
+commaSeparated item endByte = do
+  w <- A.peekWord8'
+  if w == endByte
+    then A.anyWord8 >> return []
+    else loop
+  where
+    loop = do
+      v <- item <* skipSpace
+      ch <- A.satisfy $ \w -> w == COMMA || w == endByte
+      if ch == COMMA
+        then skipSpace >> (v:) <$> loop
+        else return [v]
+{-# INLINE commaSeparated #-}
+
 arrayValues :: Parser Value -> Parser (Vector Value)
 arrayValues val = do
   skipSpace
-  vals <- ((val <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char ']'
-  return (Vector.fromList vals)
+  Vector.fromList <$> commaSeparated val CLOSE_SQUARE
 {-# INLINE arrayValues #-}
 
 -- | Parse any JSON value.  You should usually 'json' in preference to
@@ -126,64 +163,57 @@
 -- implementations in other languages conform to that same restriction
 -- to preserve interoperability and security.
 value :: Parser Value
-value = most <|> (Number <$> number)
- where
-  most = do
-    c <- satisfy (`B8.elem` "{[\"ftn")
-    case c of
-      '{' -> object_
-      '[' -> array_
-      '"' -> String <$> jstring_
-      'f' -> string "alse" *> pure (Bool False)
-      't' -> string "rue" *> pure (Bool True)
-      'n' -> string "ull" *> pure Null
-      _   -> error "attoparsec panic! the impossible happened!"
+value = do
+  w <- A.peekWord8'
+  case w of
+    DOUBLE_QUOTE  -> A.anyWord8 *> (String <$> jstring_)
+    OPEN_CURLY    -> A.anyWord8 *> object_
+    OPEN_SQUARE   -> A.anyWord8 *> array_
+    C_f           -> string "false" *> pure (Bool False)
+    C_t           -> string "true" *> pure (Bool True)
+    C_n           -> string "null" *> pure Null
+    _              | w >= 48 && w <= 57 || w == 45
+                  -> Number <$> rational
+      | otherwise -> fail "not a valid json value"
 
 -- | Strict version of 'value'. See also 'json''.
 value' :: Parser Value
-value' = most <|> num
- where
-  most = do
-    c <- satisfy (`B8.elem` "{[\"ftn")
-    case c of
-      '{' -> object_'
-      '[' -> array_'
-      '"' -> do
-          !s <- jstring_
-          return (String s)
-      'f' -> string "alse" *> pure (Bool False)
-      't' -> string "rue" *> pure (Bool True)
-      'n' -> string "ull" *> pure Null
-      _   -> error "attoparsec panic! the impossible happened!"
-  num = do
-    !n <- number
-    return (Number n)
-
-doubleQuote, backslash :: Word8
-doubleQuote = 34
-backslash = 92
-{-# INLINE backslash #-}
-{-# INLINE doubleQuote #-}
+value' = do
+  w <- A.peekWord8'
+  case w of
+    DOUBLE_QUOTE  -> do
+                     !s <- A.anyWord8 *> jstring_
+                     return (String s)
+    OPEN_CURLY    -> A.anyWord8 *> object_'
+    OPEN_SQUARE   -> A.anyWord8 *> array_'
+    C_f           -> string "false" *> pure (Bool False)
+    C_t           -> string "true" *> pure (Bool True)
+    C_n           -> string "null" *> pure Null
+    _              | w >= 48 && w <= 57 || w == 45
+                  -> do
+                     !n <- rational
+                     return (Number n)
+      | otherwise -> fail "not a valid json value"
 
 -- | Parse a quoted JSON string.
 jstring :: Parser Text
-jstring = A.word8 doubleQuote *> jstring_
+jstring = A.word8 DOUBLE_QUOTE *> jstring_
 
 -- | Parse a string without a leading quote.
 jstring_ :: Parser Text
 jstring_ = {-# SCC "jstring_" #-} do
   s <- A.scan False $ \s c -> if s then Just False
-                                   else if c == doubleQuote
+                                   else if c == DOUBLE_QUOTE
                                         then Nothing
-                                        else Just (c == backslash)
-  _ <- A.word8 doubleQuote
-  s' <- if backslash `B.elem` s
+                                        else Just (c == BACKSLASH)
+  _ <- A.word8 DOUBLE_QUOTE
+  s1 <- if BACKSLASH `B.elem` s
         then case Z.parse unescape s of
             Right r  -> return r
             Left err -> fail err
          else return s
 
-  case decodeUtf8' s' of
+  case decodeUtf8' s1 of
       Right r  -> return r
       Left err -> fail $ show err
 
@@ -192,7 +222,7 @@
 unescape :: Z.Parser ByteString
 unescape = toByteString <$> go mempty where
   go acc = do
-    h <- Z.takeWhile (/=backslash)
+    h <- Z.takeWhile (/=BACKSLASH)
     let rest = do
           start <- Z.take 2
           let !slash = B.unsafeHead start
@@ -200,37 +230,37 @@
               escape = case B.findIndex (==t) "\"\\/ntbrfu" of
                          Just i -> i
                          _      -> 255
-          if slash /= backslash || escape == 255
+          if slash /= BACKSLASH || escape == 255
             then fail "invalid JSON escape sequence"
             else do
-            let cont m = go (acc `mappend` fromByteString h `mappend` m)
+            let cont m = go (acc `mappend` byteString h `mappend` m)
                 {-# INLINE cont #-}
             if t /= 117 -- 'u'
-              then cont (fromWord8 (B.unsafeIndex mapping escape))
+              then cont (word8 (B.unsafeIndex mapping escape))
               else do
                    a <- hexQuad
                    if a < 0xd800 || a > 0xdfff
-                     then cont (fromChar (chr a))
+                     then cont (charUtf8 (chr a))
                      else do
                        b <- Z.string "\\u" *> hexQuad
                        if a <= 0xdbff && b >= 0xdc00 && b <= 0xdfff
                          then let !c = ((a - 0xd800) `shiftL` 10) +
                                        (b - 0xdc00) + 0x10000
-                              in cont (fromChar (chr c))
+                              in cont (charUtf8 (chr c))
                          else fail "invalid UTF-16 surrogates"
     done <- Z.atEnd
     if done
-      then return (acc `mappend` fromByteString h)
+      then return (acc `mappend` byteString h)
       else rest
   mapping = "\"\\/\n\t\b\r\f"
 
 hexQuad :: Z.Parser Int
 hexQuad = do
   s <- Z.take 4
-  let hex n | w >= 48 && w <= 57  = w - 48
-            | w >= 97 && w <= 122 = w - 87
-            | w >= 65 && w <= 90  = w - 55
-            | otherwise           = 255
+  let hex n | w >= C_0 && w <= C_9 = w - C_0
+            | w >= C_a && w <= C_f = w - 87
+            | w >= C_A && w <= C_F = w - 55
+            | otherwise          = 255
         where w = fromIntegral $ B.unsafeIndex s n
       a = hex 0; b = hex 1; c = hex 2; d = hex 3
   if (a .|. b .|. c .|. d) /= 255
@@ -249,11 +279,9 @@
 decodeStrictWith :: Parser Value -> (Value -> Result a) -> B.ByteString
                  -> Maybe a
 decodeStrictWith p to s =
-    case A.parse p s of
-      A.Done _ v -> case to v of
-                      Success a -> Just a
-                      _         -> Nothing
-      _          -> Nothing
+    case either Error to (A.parseOnly p s) of
+      Success a -> Just a
+      Error _ -> Nothing
 {-# INLINE decodeStrictWith #-}
 
 eitherDecodeWith :: Parser Value -> (Value -> Result a) -> L.ByteString
@@ -269,12 +297,9 @@
 eitherDecodeStrictWith :: Parser Value -> (Value -> Result a) -> B.ByteString
                        -> Either String a
 eitherDecodeStrictWith p to s =
-    case A.parse p s of
-      A.Done _ v -> case to v of
-                      Success a -> Right a
-                      Error msg -> Left msg
-      A.Fail _ _ msg -> Left msg
-      A.Partial _    -> Left "incomplete input"
+    case either Error to (A.parseOnly p s) of
+      Success a -> Right a
+      Error msg -> Left msg
 {-# INLINE eitherDecodeStrictWith #-}
 
 -- $lazy
@@ -305,3 +330,22 @@
 -- end-of-input.  See also: 'json''.
 jsonEOF' :: Parser Value
 jsonEOF' = json' <* skipSpace <* endOfInput
+
+#if defined(USE_BLAZE_BUILDER)
+byteString :: ByteString -> Builder
+byteString = fromByteString
+{-# INLINE byteString #-}
+
+charUtf8 :: Char -> Builder
+charUtf8 = fromChar
+{-# INLINE charUtf8 #-}
+
+word8 :: Word8 -> Builder
+word8 = fromWord8
+{-# INLINE word8 #-}
+
+#else
+toByteString :: Builder -> ByteString
+toByteString = L.toStrict . toLazyByteString
+{-# INLINE toByteString #-}
+#endif
diff --git a/Data/Aeson/Types.hs b/Data/Aeson/Types.hs
--- a/Data/Aeson/Types.hs
+++ b/Data/Aeson/Types.hs
@@ -47,6 +47,7 @@
     , withText
     , withArray
     , withNumber
+    , withScientific
     , withBool
 
     -- * Constructors and accessors
@@ -63,7 +64,7 @@
     , defaultTaggedObject
     ) where
 
-import Data.Aeson.Types.Class
+import Data.Aeson.Types.Instances
 import Data.Aeson.Types.Internal
 
 #ifdef GENERICS
diff --git a/Data/Aeson/Types/Class.hs b/Data/Aeson/Types/Class.hs
--- a/Data/Aeson/Types/Class.hs
+++ b/Data/Aeson/Types/Class.hs
@@ -1,7 +1,4 @@
-{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, FlexibleInstances,
-    GeneralizedNewtypeDeriving, IncoherentInstances, OverlappingInstances,
-    OverloadedStrings, UndecidableInstances, ViewPatterns #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP, FlexibleContexts #-}
 
 #ifdef GENERICS
 {-# LANGUAGE DefaultSignatures #-}
@@ -9,7 +6,7 @@
 
 -- |
 -- Module:      Data.Aeson.Types.Class
--- Copyright:   (c) 2011, 2012 Bryan O'Sullivan
+-- Copyright:   (c) 2011-2013 Bryan O'Sullivan
 --              (c) 2011 MailRank, Inc.
 -- License:     Apache
 -- Maintainer:  Bryan O'Sullivan <bos@serpentine.com>
@@ -31,61 +28,9 @@
     , genericToJSON
     , genericParseJSON
 #endif
-    -- * Types
-    , DotNetTime(..)
-
-      -- * Inspecting @'Value's@
-    , withObject
-    , withText
-    , withArray
-    , withNumber
-    , withBool
-
-    -- * Functions
-    , fromJSON
-    , (.:)
-    , (.:?)
-    , (.!=)
-    , (.=)
-    , typeMismatch
     ) where
 
-import Control.Applicative ((<$>), (<*>), (<|>), pure, empty)
-import Data.Aeson.Functions
 import Data.Aeson.Types.Internal
-import Data.Attoparsec.Char8 (Number(..))
-import Data.Fixed
-import Data.Hashable (Hashable(..))
-import Data.Int (Int8, Int16, Int32, Int64)
-import Data.Maybe (fromMaybe)
-import Data.Monoid (Dual(..), First(..), Last(..), mappend)
-import Data.Ratio (Ratio)
-import Data.Text (Text, pack, unpack)
-import Data.Text.Encoding (encodeUtf8)
-import Data.Time (UTCTime, ZonedTime(..), TimeZone(..))
-import Data.Time.Format (FormatTime, formatTime, parseTime)
-import Data.Traversable (traverse)
-import Data.Typeable (Typeable)
-import Data.Vector (Vector)
-import Data.Word (Word, Word8, Word16, Word32, Word64)
-import Foreign.Storable (Storable)
-import System.Locale (defaultTimeLocale, dateTimeFmt)
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Lazy as LB
-import qualified Data.HashMap.Strict as H
-import qualified Data.HashSet as HashSet
-import qualified Data.IntMap as IntMap
-import qualified Data.IntSet as IntSet
-import qualified Data.Map as M
-import qualified Data.Set as Set
-import qualified Data.Text as T
-import qualified Data.Text.Lazy as LT
-import qualified Data.Vector as V
-import qualified Data.Vector.Generic as VG
-import qualified Data.Vector.Primitive as VP
-import qualified Data.Vector.Storable as VS
-import qualified Data.Vector.Unboxed as VU
-import qualified Data.Vector.Mutable as VM ( unsafeNew, unsafeWrite )
 
 #ifdef GENERICS
 import GHC.Generics
@@ -245,650 +190,3 @@
     default parseJSON :: (Generic a, GFromJSON (Rep a)) => Value -> Parser a
     parseJSON = genericParseJSON defaultOptions
 #endif
-
-instance (ToJSON a) => ToJSON (Maybe a) where
-    toJSON (Just a) = toJSON a
-    toJSON Nothing  = Null
-    {-# INLINE toJSON #-}
-
-instance (FromJSON a) => FromJSON (Maybe a) where
-    parseJSON Null   = pure Nothing
-    parseJSON a      = Just <$> parseJSON a
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
-    toJSON (Left a)  = object [left  .= a]
-    toJSON (Right b) = object [right .= b]
-    {-# INLINE toJSON #-}
-
-instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
-    parseJSON (Object (H.toList -> [(key, value)]))
-        | key == left  = Left  <$> parseJSON value
-        | key == right = Right <$> parseJSON value
-    parseJSON _        = fail ""
-    {-# INLINE parseJSON #-}
-
-left, right :: Text
-left  = "Left"
-right = "Right"
-
-instance ToJSON Bool where
-    toJSON = Bool
-    {-# INLINE toJSON #-}
-
-instance FromJSON Bool where
-    parseJSON = withBool "Bool" pure
-    {-# INLINE parseJSON #-}
-
-instance ToJSON () where
-    toJSON _ = emptyArray
-    {-# INLINE toJSON #-}
-
-instance FromJSON () where
-    parseJSON = withArray "()" $ \v ->
-                  if V.null v
-                    then pure ()
-                    else fail "Expected an empty array"
-    {-# INLINE parseJSON #-}
-
-instance ToJSON [Char] where
-    toJSON = String . T.pack
-    {-# INLINE toJSON #-}
-
-instance FromJSON [Char] where
-    parseJSON = withText "String" $ pure . T.unpack
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Char where
-    toJSON = String . T.singleton
-    {-# INLINE toJSON #-}
-
-instance FromJSON Char where
-    parseJSON = withText "Char" $ \t ->
-                  if T.compareLength t 1 == EQ
-                    then pure $ T.head t
-                    else fail "Expected a string of length 1"
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Double where
-    toJSON = Number . D
-    {-# INLINE toJSON #-}
-
-instance FromJSON Double where
-    parseJSON (Number n) = case n of
-                             D d -> pure d
-                             I i -> pure (fromIntegral i)
-    parseJSON Null       = pure (0/0)
-    parseJSON v          = typeMismatch "Double" v
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Number where
-    toJSON = Number
-    {-# INLINE toJSON #-}
-
-instance FromJSON Number where
-    parseJSON (Number n) = pure n
-    parseJSON Null       = pure (D (0/0))
-    parseJSON v          = typeMismatch "Number" v
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Float where
-    toJSON = Number . realToFrac
-    {-# INLINE toJSON #-}
-
-instance FromJSON Float where
-    parseJSON (Number n) = pure $ case n of
-                                    D d -> realToFrac d
-                                    I i -> fromIntegral i
-    parseJSON Null       = pure (0/0)
-    parseJSON v          = typeMismatch "Float" v
-    {-# INLINE parseJSON #-}
-
-instance ToJSON (Ratio Integer) where
-    toJSON = Number . fromRational
-    {-# INLINE toJSON #-}
-
-instance FromJSON (Ratio Integer) where
-    parseJSON = withNumber "Ration Integer" $ \n ->
-                  pure $ case n of
-                           D d -> toRational d
-                           I i -> fromIntegral i
-    {-# INLINE parseJSON #-}
-
-instance HasResolution a => ToJSON (Fixed a) where
-    toJSON = Number . realToFrac
-    {-# INLINE toJSON #-}
-
-instance HasResolution a => FromJSON (Fixed a) where
-    parseJSON (Number n) = pure $ case n of
-                                    D d -> realToFrac d
-                                    I i -> fromIntegral i
-    parseJSON v          = typeMismatch "Fixed" v
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Int where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Int where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-parseIntegral :: Integral a => Value -> Parser a
-parseIntegral = withNumber "Integral" $ pure . floor
-{-# INLINE parseIntegral #-}
-
-instance ToJSON Integer where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Integer where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Int8 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Int8 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Int16 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Int16 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Int32 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Int32 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Int64 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Int64 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Word where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Word where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Word8 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Word8 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Word16 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Word16 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Word32 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Word32 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Word64 where
-    toJSON = Number . fromIntegral
-    {-# INLINE toJSON #-}
-
-instance FromJSON Word64 where
-    parseJSON = parseIntegral
-    {-# INLINE parseJSON #-}
-
-instance ToJSON Text where
-    toJSON = String
-    {-# INLINE toJSON #-}
-
-instance FromJSON Text where
-    parseJSON = withText "Text" pure
-    {-# INLINE parseJSON #-}
-
-instance ToJSON LT.Text where
-    toJSON = String . LT.toStrict
-    {-# INLINE toJSON #-}
-
-instance FromJSON LT.Text where
-    parseJSON = withText "Lazy Text" $ pure . LT.fromStrict
-    {-# INLINE parseJSON #-}
-
-instance ToJSON B.ByteString where
-    toJSON = String . decode
-    {-# INLINE toJSON #-}
-
-instance FromJSON B.ByteString where
-    parseJSON = withText "ByteString" $ pure . encodeUtf8
-    {-# INLINE parseJSON #-}
-
-instance ToJSON LB.ByteString where
-    toJSON = toJSON . strict
-    {-# INLINE toJSON #-}
-
-instance FromJSON LB.ByteString where
-    parseJSON = withText "Lazy ByteString" $ pure . lazy
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON a) => ToJSON [a] where
-    toJSON = Array . V.fromList . map toJSON
-    {-# INLINE toJSON #-}
-
-instance (FromJSON a) => FromJSON [a] where
-    parseJSON = withArray "[a]" $ mapM parseJSON . V.toList
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON a) => ToJSON (Vector a) where
-    toJSON = Array . V.map toJSON
-    {-# INLINE toJSON #-}
-
-instance (FromJSON a) => FromJSON (Vector a) where
-    parseJSON = withArray "Vector a" $ V.mapM parseJSON
-    {-# INLINE parseJSON #-}
-
-vectorToJSON :: (VG.Vector v a, ToJSON a) => v a -> Value
-vectorToJSON = Array . V.map toJSON . V.convert
-{-# INLINE vectorToJSON #-}
-
-vectorParseJSON :: (FromJSON a, VG.Vector w a) => String -> Value -> Parser (w a)
-vectorParseJSON s = withArray s $ fmap V.convert . V.mapM parseJSON
-{-# INLINE vectorParseJSON #-}
-
-instance (Storable a, ToJSON a) => ToJSON (VS.Vector a) where
-    toJSON = vectorToJSON
-
-instance (Storable a, FromJSON a) => FromJSON (VS.Vector a) where
-    parseJSON = vectorParseJSON "Data.Vector.Storable.Vector a"
-
-instance (VP.Prim a, ToJSON a) => ToJSON (VP.Vector a) where
-    toJSON = vectorToJSON
-
-instance (VP.Prim a, FromJSON a) => FromJSON (VP.Vector a) where
-    parseJSON = vectorParseJSON "Data.Vector.Primitive.Vector a"
-
-instance (VG.Vector VU.Vector a, ToJSON a) => ToJSON (VU.Vector a) where
-    toJSON = vectorToJSON
-
-instance (VG.Vector VU.Vector a, FromJSON a) => FromJSON (VU.Vector a) where
-    parseJSON = vectorParseJSON "Data.Vector.Unboxed.Vector a"
-
-instance (ToJSON a) => ToJSON (Set.Set a) where
-    toJSON = toJSON . Set.toList
-    {-# INLINE toJSON #-}
-
-instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
-    parseJSON = fmap Set.fromList . parseJSON
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON a) => ToJSON (HashSet.HashSet a) where
-    toJSON = toJSON . HashSet.toList
-    {-# INLINE toJSON #-}
-
-instance (Eq a, Hashable a, FromJSON a) => FromJSON (HashSet.HashSet a) where
-    parseJSON = fmap HashSet.fromList . parseJSON
-    {-# INLINE parseJSON #-}
-
-instance ToJSON IntSet.IntSet where
-    toJSON = toJSON . IntSet.toList
-    {-# INLINE toJSON #-}
-
-instance FromJSON IntSet.IntSet where
-    parseJSON = fmap IntSet.fromList . parseJSON
-    {-# INLINE parseJSON #-}
-
-instance ToJSON a => ToJSON (IntMap.IntMap a) where
-    toJSON = toJSON . IntMap.toList
-    {-# INLINE toJSON #-}
-
-instance FromJSON a => FromJSON (IntMap.IntMap a) where
-    parseJSON = fmap IntMap.fromList . parseJSON
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON v) => ToJSON (M.Map Text v) where
-    toJSON = Object . M.foldrWithKey (\k -> H.insert k . toJSON) H.empty
-    {-# INLINE toJSON #-}
-
-instance (FromJSON v) => FromJSON (M.Map Text v) where
-    parseJSON = withObject "Map Text a" $
-                  fmap (H.foldrWithKey M.insert M.empty) . traverse parseJSON
-
-instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
-    toJSON = Object . mapHashKeyVal LT.toStrict toJSON
-
-instance (FromJSON v) => FromJSON (M.Map LT.Text v) where
-    parseJSON = fmap (hashMapKey LT.fromStrict) . parseJSON
-
-instance (ToJSON v) => ToJSON (M.Map String v) where
-    toJSON = Object . mapHashKeyVal pack toJSON
-
-instance (FromJSON v) => FromJSON (M.Map String v) where
-    parseJSON = fmap (hashMapKey unpack) . parseJSON
-
-instance (ToJSON v) => ToJSON (M.Map B.ByteString v) where
-    toJSON = Object . mapHashKeyVal decode toJSON
-
-instance (FromJSON v) => FromJSON (M.Map B.ByteString v) where
-    parseJSON = fmap (hashMapKey encodeUtf8) . parseJSON
-
-instance (ToJSON v) => ToJSON (M.Map LB.ByteString v) where
-    toJSON = Object . mapHashKeyVal strict toJSON
-
-instance (FromJSON v) => FromJSON (M.Map LB.ByteString v) where
-    parseJSON = fmap (hashMapKey lazy) . parseJSON
-
-instance (ToJSON v) => ToJSON (H.HashMap Text v) where
-    toJSON = Object . H.map toJSON
-    {-# INLINE toJSON #-}
-
-instance (FromJSON v) => FromJSON (H.HashMap Text v) where
-    parseJSON = withObject "HashMap Text a" $ traverse parseJSON
-
-instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
-    toJSON = Object . mapKeyVal LT.toStrict toJSON
-
-instance (FromJSON v) => FromJSON (H.HashMap LT.Text v) where
-    parseJSON = fmap (mapKey LT.fromStrict) . parseJSON
-
-instance (ToJSON v) => ToJSON (H.HashMap String v) where
-    toJSON = Object . mapKeyVal pack toJSON
-
-instance (FromJSON v) => FromJSON (H.HashMap String v) where
-    parseJSON = fmap (mapKey unpack) . parseJSON
-
-instance (ToJSON v) => ToJSON (H.HashMap B.ByteString v) where
-    toJSON = Object . mapKeyVal decode toJSON
-
-instance (FromJSON v) => FromJSON (H.HashMap B.ByteString v) where
-    parseJSON = fmap (mapKey encodeUtf8) . parseJSON
-
-instance (ToJSON v) => ToJSON (H.HashMap LB.ByteString v) where
-    toJSON = Object . mapKeyVal strict toJSON
-
-instance (FromJSON v) => FromJSON (H.HashMap LB.ByteString v) where
-    parseJSON = fmap (mapKey lazy) . parseJSON
-
-instance ToJSON Value where
-    toJSON a = a
-    {-# INLINE toJSON #-}
-
-instance FromJSON Value where
-    parseJSON a = pure a
-    {-# INLINE parseJSON #-}
-
--- | A newtype wrapper for 'UTCTime' that uses the same non-standard
--- serialization format as Microsoft .NET, whose @System.DateTime@
--- type is by default serialized to JSON as in the following example:
---
--- > /Date(1302547608878)/
---
--- The number represents milliseconds since the Unix epoch.
-newtype DotNetTime = DotNetTime {
-      fromDotNetTime :: UTCTime
-    } deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
-
-instance ToJSON DotNetTime where
-    toJSON (DotNetTime t) =
-        String (pack (secs ++ msecs ++ ")/"))
-      where secs  = formatTime defaultTimeLocale "/Date(%s" t
-            msecs = take 3 $ formatTime defaultTimeLocale "%q" t
-    {-# INLINE toJSON #-}
-
-instance FromJSON DotNetTime where
-    parseJSON = withText "DotNetTime" $ \t ->
-        let (s,m) = T.splitAt (T.length t - 5) t
-            t'    = T.concat [s,".",m]
-        in case parseTime defaultTimeLocale "/Date(%s%Q)/" (unpack t') of
-             Just d -> pure (DotNetTime d)
-             _      -> fail "could not parse .NET time"
-    {-# INLINE parseJSON #-}
-
-instance ToJSON ZonedTime where
-    toJSON t = String $ pack $ formatTime defaultTimeLocale format t
-      where
-        format = "%FT%T" ++ milliseconds ++ tzFormat
-        milliseconds = take 4 $ formatTime defaultTimeLocale "%Q" t
-        tzFormat
-          | 0 == timeZoneMinutes (zonedTimeZone t) = "Z"
-          | otherwise = "%z"
-
-instance FromJSON ZonedTime where
-    parseJSON (String t) =
-      tryFormats alternateFormats
-      <|> fail "could not parse ECMA-262 ISO-8601 date"
-      where
-        tryFormat f =
-          case parseTime defaultTimeLocale f (unpack t) of
-            Just d -> pure d
-            Nothing -> empty
-        tryFormats = foldr1 (<|>) . map tryFormat
-        alternateFormats =
-          dateTimeFmt defaultTimeLocale :
-          distributeList ["%Y", "%Y-%m", "%F"]
-                         ["T%R", "T%T", "T%T%Q", "T%T%QZ", "T%T%Q%z"]
-
-        distributeList xs ys =
-          foldr (\x acc -> acc ++ distribute x ys) [] xs
-        distribute x = map (mappend x)
-
-    parseJSON v = typeMismatch "ZonedTime" v
-
-instance ToJSON UTCTime where
-    toJSON t = String (pack (take 23 str ++ "Z"))
-      where str = formatTime defaultTimeLocale "%FT%T%Q" t
-    {-# INLINE toJSON #-}
-
-instance FromJSON UTCTime where
-    parseJSON = withText "UTCTime" $ \t ->
-        case parseTime defaultTimeLocale "%FT%T%QZ" (unpack t) of
-          Just d -> pure d
-          _      -> fail "could not parse ISO-8601 date"
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
-    toJSON (a,b) = Array $ V.create $ do
-                     mv <- VM.unsafeNew 2
-                     VM.unsafeWrite mv 0 (toJSON a)
-                     VM.unsafeWrite mv 1 (toJSON b)
-                     return mv
-    {-# INLINE toJSON #-}
-
-instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
-    parseJSON = withArray "(a,b)" $ \ab ->
-        let n = V.length ab
-        in if n == 2
-             then (,) <$> parseJSON (V.unsafeIndex ab 0)
-                      <*> parseJSON (V.unsafeIndex ab 1)
-             else fail $ "cannot unpack array of length " ++
-                         show n ++ " into a pair"
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON (a,b,c) where
-    toJSON (a,b,c) = Array $ V.create $ do
-                       mv <- VM.unsafeNew 3
-                       VM.unsafeWrite mv 0 (toJSON a)
-                       VM.unsafeWrite mv 1 (toJSON b)
-                       VM.unsafeWrite mv 2 (toJSON c)
-                       return mv
-    {-# INLINE toJSON #-}
-
-instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON (a,b,c) where
-    parseJSON = withArray "(a,b,c)" $ \abc ->
-        let n = V.length abc
-        in if n == 3
-             then (,,) <$> parseJSON (V.unsafeIndex abc 0)
-                       <*> parseJSON (V.unsafeIndex abc 1)
-                       <*> parseJSON (V.unsafeIndex abc 2)
-             else fail $ "cannot unpack array of length " ++
-                          show n ++ " into a 3-tuple"
-    {-# INLINE parseJSON #-}
-
-instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON (a,b,c,d) where
-    toJSON (a,b,c,d) = Array $ V.create $ do
-                         mv <- VM.unsafeNew 4
-                         VM.unsafeWrite mv 0 (toJSON a)
-                         VM.unsafeWrite mv 1 (toJSON b)
-                         VM.unsafeWrite mv 2 (toJSON c)
-                         VM.unsafeWrite mv 3 (toJSON d)
-                         return mv
-    {-# INLINE toJSON #-}
-
-instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON (a,b,c,d) where
-    parseJSON = withArray "(a,b,c,d)" $ \abcd ->
-        let n = V.length abcd
-        in if n == 4
-             then (,,,) <$> parseJSON (V.unsafeIndex abcd 0)
-                        <*> parseJSON (V.unsafeIndex abcd 1)
-                        <*> parseJSON (V.unsafeIndex abcd 2)
-                        <*> parseJSON (V.unsafeIndex abcd 3)
-             else fail $ "cannot unpack array of length " ++
-                         show n ++ " into a 4-tuple"
-    {-# INLINE parseJSON #-}
-
-instance ToJSON a => ToJSON (Dual a) where
-    toJSON = toJSON . getDual
-    {-# INLINE toJSON #-}
-
-instance FromJSON a => FromJSON (Dual a) where
-    parseJSON = fmap Dual . parseJSON
-    {-# INLINE parseJSON #-}
-
-instance ToJSON a => ToJSON (First a) where
-    toJSON = toJSON . getFirst
-    {-# INLINE toJSON #-}
-
-instance FromJSON a => FromJSON (First a) where
-    parseJSON = fmap First . parseJSON
-    {-# INLINE parseJSON #-}
-
-instance ToJSON a => ToJSON (Last a) where
-    toJSON = toJSON . getLast
-    {-# INLINE toJSON #-}
-
-instance FromJSON a => FromJSON (Last a) where
-    parseJSON = fmap Last . parseJSON
-    {-# INLINE parseJSON #-}
-
--- | @withObject expected f value@ applies @f@ to the 'Object' when @value@ is an @Object@
---   and fails using @'typeMismatch' expected@ otherwise.
-withObject :: String -> (Object -> Parser a) -> Value -> Parser a
-withObject _        f (Object obj) = f obj
-withObject expected _ v            = typeMismatch expected v
-{-# INLINE withObject #-}
-
--- | @withObject expected f value@ applies @f@ to the 'Text' when @value@ is a @String@
---   and fails using @'typeMismatch' expected@ otherwise.
-withText :: String -> (Text -> Parser a) -> Value -> Parser a
-withText _        f (String txt) = f txt
-withText expected _ v            = typeMismatch expected v
-{-# INLINE withText #-}
-
--- | @withObject expected f value@ applies @f@ to the 'Array' when @value@ is an @Array@
---   and fails using @'typeMismatch' expected@ otherwise.
-withArray :: String -> (Array -> Parser a) -> Value -> Parser a
-withArray _        f (Array arr) = f arr
-withArray expected _ v           = typeMismatch expected v
-{-# INLINE withArray #-}
-
--- | @withObject expected f value@ applies @f@ to the 'Number' when @value@ is a @Number@
---   and fails using @'typeMismatch' expected@ otherwise.
-withNumber :: String -> (Number -> Parser a) -> Value -> Parser a
-withNumber _        f (Number num) = f num
-withNumber expected _ v            = typeMismatch expected v
-{-# INLINE withNumber #-}
-
--- | @withObject expected f value@ applies @f@ to the 'Bool' when @value@ is a @Bool@
---   and fails using @'typeMismatch' expected@ otherwise.
-withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
-withBool _        f (Bool arr) = f arr
-withBool expected _ v          = typeMismatch expected v
-{-# INLINE withBool #-}
-
--- | Construct a 'Pair' from a key and a value.
-(.=) :: ToJSON a => Text -> a -> Pair
-name .= value = (name, toJSON value)
-{-# INLINE (.=) #-}
-
--- | Convert a value from JSON, failing if the types do not match.
-fromJSON :: (FromJSON a) => Value -> Result a
-fromJSON = parse parseJSON
-{-# INLINE fromJSON #-}
-
--- | Retrieve the value associated with the given key of an 'Object'.
--- The result is 'empty' if the key is not present or the value cannot
--- be converted to the desired type.
---
--- This accessor is appropriate if the key and value /must/ be present
--- in an object for it to be valid.  If the key and value are
--- optional, use '(.:?)' instead.
-(.:) :: (FromJSON a) => Object -> Text -> Parser a
-obj .: key = case H.lookup key obj of
-               Nothing -> fail $ "key " ++ show key ++ " not present"
-               Just v  -> parseJSON v
-{-# INLINE (.:) #-}
-
--- | Retrieve the value associated with the given key of an 'Object'.
--- The result is 'Nothing' if the key is not present, or 'empty' if
--- the value cannot be converted to the desired type.
---
--- This accessor is most useful if the key and value can be absent
--- from an object without affecting its validity.  If the key and
--- value are mandatory, use '(.:)' instead.
-(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
-obj .:? key = case H.lookup key obj of
-               Nothing -> pure Nothing
-               Just v  -> parseJSON v
-{-# INLINE (.:?) #-}
-
--- | Helper for use in combination with '.:?' to provide default
--- values for optional JSON object fields.
---
--- This combinator is most useful if the key and value can be absent
--- from an object without affecting its validity and we know a default
--- value to assign in that case.  If the key and value are mandatory,
--- use '(.:)' instead.
---
--- Example usage:
---
--- @ v1 <- o '.:?' \"opt_field_with_dfl\" .!= \"default_val\"
--- v2 <- o '.:'  \"mandatory_field\"
--- v3 <- o '.:?' \"opt_field2\"
--- @
-(.!=) :: Parser (Maybe a) -> a -> Parser a
-pmval .!= val = fromMaybe val <$> pmval
-{-# INLINE (.!=) #-}
-
--- | Fail parsing due to a type mismatch, with a descriptive message.
-typeMismatch :: String -- ^ The name of the type you are trying to parse.
-             -> Value  -- ^ The actual value encountered.
-             -> Parser a
-typeMismatch expected actual =
-    fail $ "when expecting a " ++ expected ++ ", encountered " ++ name ++
-           " instead"
-  where
-    name = case actual of
-             Object _ -> "Object"
-             Array _  -> "Array"
-             String _ -> "String"
-             Number _ -> "Number"
-             Bool _   -> "Boolean"
-             Null     -> "Null"
diff --git a/Data/Aeson/Types/Generic.hs b/Data/Aeson/Types/Generic.hs
--- a/Data/Aeson/Types/Generic.hs
+++ b/Data/Aeson/Types/Generic.hs
@@ -22,7 +22,7 @@
 import Control.Applicative ((<*>), (<$>), (<|>), pure)
 import Control.Monad ((<=<))
 import Control.Monad.ST (ST)
-import Data.Aeson.Types.Class
+import Data.Aeson.Types.Instances
 import Data.Aeson.Types.Internal
 import Data.Bits
 import Data.DList (DList, toList, empty)
diff --git a/Data/Aeson/Types/Instances.hs b/Data/Aeson/Types/Instances.hs
new file mode 100644
--- /dev/null
+++ b/Data/Aeson/Types/Instances.hs
@@ -0,0 +1,795 @@
+{-# LANGUAGE CPP, DeriveDataTypeable, FlexibleContexts, FlexibleInstances,
+    GeneralizedNewtypeDeriving, IncoherentInstances, OverlappingInstances,
+    OverloadedStrings, UndecidableInstances, ViewPatterns #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+#ifdef GENERICS
+{-# LANGUAGE DefaultSignatures #-}
+#endif
+
+-- |
+-- Module:      Data.Aeson.Types.Instances
+-- Copyright:   (c) 2011-2013 Bryan O'Sullivan
+--              (c) 2011 MailRank, Inc.
+-- License:     Apache
+-- Maintainer:  Bryan O'Sullivan <bos@serpentine.com>
+-- Stability:   experimental
+-- Portability: portable
+--
+-- Types for working with JSON data.
+
+module Data.Aeson.Types.Instances
+    (
+    -- * Type classes
+    -- ** Core JSON classes
+      FromJSON(..)
+    , ToJSON(..)
+#ifdef GENERICS
+    -- ** Generic JSON classes
+    , GFromJSON(..)
+    , GToJSON(..)
+    , genericToJSON
+    , genericParseJSON
+#endif
+    -- * Types
+    , DotNetTime(..)
+
+      -- * Inspecting @'Value's@
+    , withObject
+    , withText
+    , withArray
+    , withNumber
+    , withScientific
+    , withBool
+
+    -- * Functions
+    , fromJSON
+    , (.:)
+    , (.:?)
+    , (.!=)
+    , (.=)
+    , typeMismatch
+    ) where
+
+import Control.Applicative ((<$>), (<*>), (<|>), pure, empty)
+import Data.Aeson.Functions
+import Data.Aeson.Types.Class
+import Data.Aeson.Types.Internal
+import Data.Scientific (Scientific)
+import qualified Data.Scientific as Scientific (coefficient, base10Exponent, fromFloatDigits)
+import Data.Attoparsec.Number (Number(..))
+import Data.Fixed
+import Data.Hashable (Hashable(..))
+import Data.Int (Int8, Int16, Int32, Int64)
+import Data.Maybe (fromMaybe)
+import Data.Monoid (Dual(..), First(..), Last(..), mappend)
+import Data.Ratio (Ratio, (%), numerator, denominator)
+import Data.Text (Text, pack, unpack)
+import Data.Time (UTCTime, ZonedTime(..), TimeZone(..))
+import Data.Time.Format (FormatTime, formatTime, parseTime)
+import Data.Traversable (traverse)
+import Data.Vector (Vector)
+import Data.Word (Word, Word8, Word16, Word32, Word64)
+import Foreign.Storable (Storable)
+import System.Locale (defaultTimeLocale, dateTimeFmt)
+import qualified Data.HashMap.Strict as H
+import qualified Data.HashSet as HashSet
+import qualified Data.IntMap as IntMap
+import qualified Data.IntSet as IntSet
+import qualified Data.Map as M
+import qualified Data.Set as Set
+import qualified Data.Tree as Tree
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as LT
+import qualified Data.Vector as V
+import qualified Data.Vector.Generic as VG
+import qualified Data.Vector.Primitive as VP
+import qualified Data.Vector.Storable as VS
+import qualified Data.Vector.Unboxed as VU
+import qualified Data.Vector.Mutable as VM ( unsafeNew, unsafeWrite )
+
+instance (ToJSON a) => ToJSON (Maybe a) where
+    toJSON (Just a) = toJSON a
+    toJSON Nothing  = Null
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a) => FromJSON (Maybe a) where
+    parseJSON Null   = pure Nothing
+    parseJSON a      = Just <$> parseJSON a
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
+    toJSON (Left a)  = object [left  .= a]
+    toJSON (Right b) = object [right .= b]
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
+    parseJSON (Object (H.toList -> [(key, value)]))
+        | key == left  = Left  <$> parseJSON value
+        | key == right = Right <$> parseJSON value
+    parseJSON _        = fail ""
+    {-# INLINE parseJSON #-}
+
+left, right :: Text
+left  = "Left"
+right = "Right"
+
+instance ToJSON Bool where
+    toJSON = Bool
+    {-# INLINE toJSON #-}
+
+instance FromJSON Bool where
+    parseJSON = withBool "Bool" pure
+    {-# INLINE parseJSON #-}
+
+instance ToJSON () where
+    toJSON _ = emptyArray
+    {-# INLINE toJSON #-}
+
+instance FromJSON () where
+    parseJSON = withArray "()" $ \v ->
+                  if V.null v
+                    then pure ()
+                    else fail "Expected an empty array"
+    {-# INLINE parseJSON #-}
+
+instance ToJSON [Char] where
+    toJSON = String . T.pack
+    {-# INLINE toJSON #-}
+
+instance FromJSON [Char] where
+    parseJSON = withText "String" $ pure . T.unpack
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Char where
+    toJSON = String . T.singleton
+    {-# INLINE toJSON #-}
+
+instance FromJSON Char where
+    parseJSON = withText "Char" $ \t ->
+                  if T.compareLength t 1 == EQ
+                    then pure $ T.head t
+                    else fail "Expected a string of length 1"
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Scientific where
+    toJSON = Number
+    {-# INLINE toJSON #-}
+
+instance FromJSON Scientific where
+    parseJSON = withScientific "Scientific" pure
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Double where
+    toJSON = realFloatToJSON
+    {-# INLINE toJSON #-}
+
+realFloatToJSON :: RealFloat a => a -> Value
+realFloatToJSON d
+    | isNaN d || isInfinite d = Null
+    | otherwise = Number $ Scientific.fromFloatDigits d
+{-# INLINE realFloatToJSON #-}
+
+instance FromJSON Double where
+    parseJSON (Number s) = pure $ realToFrac s
+    parseJSON Null       = pure (0/0)
+    parseJSON v          = typeMismatch "Double" v
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Number where
+    toJSON (D d) = toJSON d
+    toJSON (I i) = toJSON i
+    {-# INLINE toJSON #-}
+
+instance FromJSON Number where
+    parseJSON (Number s) = pure $ scientificToNumber s
+    parseJSON Null       = pure (D (0/0))
+    parseJSON v          = typeMismatch "Number" v
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Float where
+    toJSON = realFloatToJSON
+    {-# INLINE toJSON #-}
+
+instance FromJSON Float where
+    parseJSON (Number s) = pure $ realToFrac s
+    parseJSON Null       = pure (0/0)
+    parseJSON v          = typeMismatch "Float" v
+    {-# INLINE parseJSON #-}
+
+instance ToJSON (Ratio Integer) where
+    toJSON r = object [ "numerator"   .= numerator   r
+                      , "denominator" .= denominator r
+                      ]
+    {-# INLINE toJSON #-}
+
+instance FromJSON (Ratio Integer) where
+    parseJSON = withObject "Rational" $ \obj ->
+                  (%) <$> obj .: "numerator"
+                      <*> obj .: "denominator"
+    {-# INLINE parseJSON #-}
+
+instance HasResolution a => ToJSON (Fixed a) where
+    toJSON = Number . realToFrac
+    {-# INLINE toJSON #-}
+
+instance HasResolution a => FromJSON (Fixed a) where
+    parseJSON = withScientific "Fixed" $ pure . realToFrac
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Int where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Int where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+parseIntegral :: Integral a => Value -> Parser a
+parseIntegral = withScientific "Integral" $ pure . floor
+{-# INLINE parseIntegral #-}
+
+instance ToJSON Integer where
+    toJSON = Number . fromInteger
+    {-# INLINE toJSON #-}
+
+instance FromJSON Integer where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Int8 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Int8 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Int16 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Int16 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Int32 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Int32 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Int64 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Int64 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Word where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Word where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Word8 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Word8 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Word16 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Word16 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Word32 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Word32 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Word64 where
+    toJSON = Number . fromIntegral
+    {-# INLINE toJSON #-}
+
+instance FromJSON Word64 where
+    parseJSON = parseIntegral
+    {-# INLINE parseJSON #-}
+
+instance ToJSON Text where
+    toJSON = String
+    {-# INLINE toJSON #-}
+
+instance FromJSON Text where
+    parseJSON = withText "Text" pure
+    {-# INLINE parseJSON #-}
+
+instance ToJSON LT.Text where
+    toJSON = String . LT.toStrict
+    {-# INLINE toJSON #-}
+
+instance FromJSON LT.Text where
+    parseJSON = withText "Lazy Text" $ pure . LT.fromStrict
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a) => ToJSON [a] where
+    toJSON = Array . V.fromList . map toJSON
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a) => FromJSON [a] where
+    parseJSON = withArray "[a]" $ mapM parseJSON . V.toList
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a) => ToJSON (Vector a) where
+    toJSON = Array . V.map toJSON
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a) => FromJSON (Vector a) where
+    parseJSON = withArray "Vector a" $ V.mapM parseJSON
+    {-# INLINE parseJSON #-}
+
+vectorToJSON :: (VG.Vector v a, ToJSON a) => v a -> Value
+vectorToJSON = Array . V.map toJSON . V.convert
+{-# INLINE vectorToJSON #-}
+
+vectorParseJSON :: (FromJSON a, VG.Vector w a) => String -> Value -> Parser (w a)
+vectorParseJSON s = withArray s $ fmap V.convert . V.mapM parseJSON
+{-# INLINE vectorParseJSON #-}
+
+instance (Storable a, ToJSON a) => ToJSON (VS.Vector a) where
+    toJSON = vectorToJSON
+
+instance (Storable a, FromJSON a) => FromJSON (VS.Vector a) where
+    parseJSON = vectorParseJSON "Data.Vector.Storable.Vector a"
+
+instance (VP.Prim a, ToJSON a) => ToJSON (VP.Vector a) where
+    toJSON = vectorToJSON
+
+instance (VP.Prim a, FromJSON a) => FromJSON (VP.Vector a) where
+    parseJSON = vectorParseJSON "Data.Vector.Primitive.Vector a"
+
+instance (VG.Vector VU.Vector a, ToJSON a) => ToJSON (VU.Vector a) where
+    toJSON = vectorToJSON
+
+instance (VG.Vector VU.Vector a, FromJSON a) => FromJSON (VU.Vector a) where
+    parseJSON = vectorParseJSON "Data.Vector.Unboxed.Vector a"
+
+instance (ToJSON a) => ToJSON (Set.Set a) where
+    toJSON = toJSON . Set.toList
+    {-# INLINE toJSON #-}
+
+instance (Ord a, FromJSON a) => FromJSON (Set.Set a) where
+    parseJSON = fmap Set.fromList . parseJSON
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a) => ToJSON (HashSet.HashSet a) where
+    toJSON = toJSON . HashSet.toList
+    {-# INLINE toJSON #-}
+
+instance (Eq a, Hashable a, FromJSON a) => FromJSON (HashSet.HashSet a) where
+    parseJSON = fmap HashSet.fromList . parseJSON
+    {-# INLINE parseJSON #-}
+
+instance ToJSON IntSet.IntSet where
+    toJSON = toJSON . IntSet.toList
+    {-# INLINE toJSON #-}
+
+instance FromJSON IntSet.IntSet where
+    parseJSON = fmap IntSet.fromList . parseJSON
+    {-# INLINE parseJSON #-}
+
+instance ToJSON a => ToJSON (IntMap.IntMap a) where
+    toJSON = toJSON . IntMap.toList
+    {-# INLINE toJSON #-}
+
+instance FromJSON a => FromJSON (IntMap.IntMap a) where
+    parseJSON = fmap IntMap.fromList . parseJSON
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON v) => ToJSON (M.Map Text v) where
+    toJSON = Object . M.foldrWithKey (\k -> H.insert k . toJSON) H.empty
+    {-# INLINE toJSON #-}
+
+instance (FromJSON v) => FromJSON (M.Map Text v) where
+    parseJSON = withObject "Map Text a" $
+                  fmap (H.foldrWithKey M.insert M.empty) . traverse parseJSON
+
+instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
+    toJSON = Object . mapHashKeyVal LT.toStrict toJSON
+
+instance (FromJSON v) => FromJSON (M.Map LT.Text v) where
+    parseJSON = fmap (hashMapKey LT.fromStrict) . parseJSON
+
+instance (ToJSON v) => ToJSON (M.Map String v) where
+    toJSON = Object . mapHashKeyVal pack toJSON
+
+instance (FromJSON v) => FromJSON (M.Map String v) where
+    parseJSON = fmap (hashMapKey unpack) . parseJSON
+
+instance (ToJSON v) => ToJSON (H.HashMap Text v) where
+    toJSON = Object . H.map toJSON
+    {-# INLINE toJSON #-}
+
+instance (FromJSON v) => FromJSON (H.HashMap Text v) where
+    parseJSON = withObject "HashMap Text a" $ traverse parseJSON
+
+instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
+    toJSON = Object . mapKeyVal LT.toStrict toJSON
+
+instance (FromJSON v) => FromJSON (H.HashMap LT.Text v) where
+    parseJSON = fmap (mapKey LT.fromStrict) . parseJSON
+
+instance (ToJSON v) => ToJSON (H.HashMap String v) where
+    toJSON = Object . mapKeyVal pack toJSON
+
+instance (FromJSON v) => FromJSON (H.HashMap String v) where
+    parseJSON = fmap (mapKey unpack) . parseJSON
+
+instance (ToJSON v) => ToJSON (Tree.Tree v) where
+    toJSON (Tree.Node root branches) = toJSON (root,branches)
+
+instance (FromJSON v) => FromJSON (Tree.Tree v) where
+    parseJSON j = uncurry Tree.Node <$> parseJSON j
+
+instance ToJSON Value where
+    toJSON a = a
+    {-# INLINE toJSON #-}
+
+instance FromJSON Value where
+    parseJSON a = pure a
+    {-# INLINE parseJSON #-}
+
+instance ToJSON DotNetTime where
+    toJSON (DotNetTime t) =
+        String (pack (secs ++ formatMillis t ++ ")/"))
+      where secs  = formatTime defaultTimeLocale "/Date(%s" t
+    {-# INLINE toJSON #-}
+
+instance FromJSON DotNetTime where
+    parseJSON = withText "DotNetTime" $ \t ->
+        let (s,m) = T.splitAt (T.length t - 5) t
+            t'    = T.concat [s,".",m]
+        in case parseTime defaultTimeLocale "/Date(%s%Q)/" (unpack t') of
+             Just d -> pure (DotNetTime d)
+             _      -> fail "could not parse .NET time"
+    {-# INLINE parseJSON #-}
+
+instance ToJSON ZonedTime where
+    toJSON t = String $ pack $ formatTime defaultTimeLocale format t
+      where
+        format = "%FT%T." ++ formatMillis t ++ tzFormat
+        tzFormat
+          | 0 == timeZoneMinutes (zonedTimeZone t) = "Z"
+          | otherwise = "%z"
+
+formatMillis :: (FormatTime t) => t -> String
+formatMillis t = take 3 . formatTime defaultTimeLocale "%q" $ t
+
+instance FromJSON ZonedTime where
+    parseJSON (String t) =
+      tryFormats alternateFormats
+      <|> fail "could not parse ECMA-262 ISO-8601 date"
+      where
+        tryFormat f =
+          case parseTime defaultTimeLocale f (unpack t) of
+            Just d -> pure d
+            Nothing -> empty
+        tryFormats = foldr1 (<|>) . map tryFormat
+        alternateFormats =
+          dateTimeFmt defaultTimeLocale :
+          distributeList ["%Y", "%Y-%m", "%F"]
+                         ["T%R", "T%T", "T%T%Q", "T%T%QZ", "T%T%Q%z"]
+
+        distributeList xs ys =
+          foldr (\x acc -> acc ++ distribute x ys) [] xs
+        distribute x = map (mappend x)
+
+    parseJSON v = typeMismatch "ZonedTime" v
+
+instance ToJSON UTCTime where
+    toJSON t = String (pack (take 23 str ++ "Z"))
+      where str = formatTime defaultTimeLocale "%FT%T.%q" t
+    {-# INLINE toJSON #-}
+
+instance FromJSON UTCTime where
+    parseJSON = withText "UTCTime" $ \t ->
+        case parseTime defaultTimeLocale "%FT%T%QZ" (unpack t) of
+          Just d -> pure d
+          _      -> fail "could not parse ISO-8601 date"
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a, ToJSON b) => ToJSON (a,b) where
+    toJSON (a,b) = Array $ V.create $ do
+                     mv <- VM.unsafeNew 2
+                     VM.unsafeWrite mv 0 (toJSON a)
+                     VM.unsafeWrite mv 1 (toJSON b)
+                     return mv
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a, FromJSON b) => FromJSON (a,b) where
+    parseJSON = withArray "(a,b)" $ \ab ->
+        let n = V.length ab
+        in if n == 2
+             then (,) <$> parseJSON (V.unsafeIndex ab 0)
+                      <*> parseJSON (V.unsafeIndex ab 1)
+             else fail $ "cannot unpack array of length " ++
+                         show n ++ " into a pair"
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a, ToJSON b, ToJSON c) => ToJSON (a,b,c) where
+    toJSON (a,b,c) = Array $ V.create $ do
+                       mv <- VM.unsafeNew 3
+                       VM.unsafeWrite mv 0 (toJSON a)
+                       VM.unsafeWrite mv 1 (toJSON b)
+                       VM.unsafeWrite mv 2 (toJSON c)
+                       return mv
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a, FromJSON b, FromJSON c) => FromJSON (a,b,c) where
+    parseJSON = withArray "(a,b,c)" $ \abc ->
+        let n = V.length abc
+        in if n == 3
+             then (,,) <$> parseJSON (V.unsafeIndex abc 0)
+                       <*> parseJSON (V.unsafeIndex abc 1)
+                       <*> parseJSON (V.unsafeIndex abc 2)
+             else fail $ "cannot unpack array of length " ++
+                          show n ++ " into a 3-tuple"
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d) => ToJSON (a,b,c,d) where
+    toJSON (a,b,c,d) = Array $ V.create $ do
+                         mv <- VM.unsafeNew 4
+                         VM.unsafeWrite mv 0 (toJSON a)
+                         VM.unsafeWrite mv 1 (toJSON b)
+                         VM.unsafeWrite mv 2 (toJSON c)
+                         VM.unsafeWrite mv 3 (toJSON d)
+                         return mv
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d) => FromJSON (a,b,c,d) where
+    parseJSON = withArray "(a,b,c,d)" $ \abcd ->
+        let n = V.length abcd
+        in if n == 4
+             then (,,,) <$> parseJSON (V.unsafeIndex abcd 0)
+                        <*> parseJSON (V.unsafeIndex abcd 1)
+                        <*> parseJSON (V.unsafeIndex abcd 2)
+                        <*> parseJSON (V.unsafeIndex abcd 3)
+             else fail $ "cannot unpack array of length " ++
+                         show n ++ " into a 4-tuple"
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e) => ToJSON (a,b,c,d,e) where
+    toJSON (a,b,c,d,e) = Array $ V.create $ do
+                           mv <- VM.unsafeNew 5
+                           VM.unsafeWrite mv 0 (toJSON a)
+                           VM.unsafeWrite mv 1 (toJSON b)
+                           VM.unsafeWrite mv 2 (toJSON c)
+                           VM.unsafeWrite mv 3 (toJSON d)
+                           VM.unsafeWrite mv 4 (toJSON e)
+                           return mv
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e) => FromJSON (a,b,c,d,e) where
+    parseJSON = withArray "(a,b,c,d,e)" $ \abcde ->
+        let n = V.length abcde
+        in if n == 5
+             then (,,,,) <$> parseJSON (V.unsafeIndex abcde 0)
+                         <*> parseJSON (V.unsafeIndex abcde 1)
+                         <*> parseJSON (V.unsafeIndex abcde 2)
+                         <*> parseJSON (V.unsafeIndex abcde 3)
+                         <*> parseJSON (V.unsafeIndex abcde 4)
+             else fail $ "cannot unpack array of length " ++
+                         show n ++ " into a 5-tuple"
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f) => ToJSON (a,b,c,d,e,f) where
+    toJSON (a,b,c,d,e,f) = Array $ V.create $ do
+                             mv <- VM.unsafeNew 6
+                             VM.unsafeWrite mv 0 (toJSON a)
+                             VM.unsafeWrite mv 1 (toJSON b)
+                             VM.unsafeWrite mv 2 (toJSON c)
+                             VM.unsafeWrite mv 3 (toJSON d)
+                             VM.unsafeWrite mv 4 (toJSON e)
+                             VM.unsafeWrite mv 5 (toJSON f)
+                             return mv
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f) => FromJSON (a,b,c,d,e,f) where
+    parseJSON = withArray "(a,b,c,d,e,f)" $ \abcdef ->
+        let n = V.length abcdef
+        in if n == 6
+             then (,,,,,) <$> parseJSON (V.unsafeIndex abcdef 0)
+                          <*> parseJSON (V.unsafeIndex abcdef 1)
+                          <*> parseJSON (V.unsafeIndex abcdef 2)
+                          <*> parseJSON (V.unsafeIndex abcdef 3)
+                          <*> parseJSON (V.unsafeIndex abcdef 4)
+                          <*> parseJSON (V.unsafeIndex abcdef 5)
+             else fail $ "cannot unpack array of length " ++
+                         show n ++ " into a 6-tuple"
+    {-# INLINE parseJSON #-}
+
+instance (ToJSON a, ToJSON b, ToJSON c, ToJSON d, ToJSON e, ToJSON f, ToJSON g) => ToJSON (a,b,c,d,e,f,g) where
+    toJSON (a,b,c,d,e,f,g) = Array $ V.create $ do
+                               mv <- VM.unsafeNew 7
+                               VM.unsafeWrite mv 0 (toJSON a)
+                               VM.unsafeWrite mv 1 (toJSON b)
+                               VM.unsafeWrite mv 2 (toJSON c)
+                               VM.unsafeWrite mv 3 (toJSON d)
+                               VM.unsafeWrite mv 4 (toJSON e)
+                               VM.unsafeWrite mv 5 (toJSON f)
+                               VM.unsafeWrite mv 6 (toJSON g)
+                               return mv
+    {-# INLINE toJSON #-}
+
+instance (FromJSON a, FromJSON b, FromJSON c, FromJSON d, FromJSON e, FromJSON f, FromJSON g) => FromJSON (a,b,c,d,e,f,g) where
+    parseJSON = withArray "(a,b,c,d,e,f,g)" $ \abcdefg ->
+        let n = V.length abcdefg
+        in if n == 7
+             then (,,,,,,) <$> parseJSON (V.unsafeIndex abcdefg 0)
+                           <*> parseJSON (V.unsafeIndex abcdefg 1)
+                           <*> parseJSON (V.unsafeIndex abcdefg 2)
+                           <*> parseJSON (V.unsafeIndex abcdefg 3)
+                           <*> parseJSON (V.unsafeIndex abcdefg 4)
+                           <*> parseJSON (V.unsafeIndex abcdefg 5)
+                           <*> parseJSON (V.unsafeIndex abcdefg 6)
+             else fail $ "cannot unpack array of length " ++
+                         show n ++ " into a 7-tuple"
+    {-# INLINE parseJSON #-}
+
+instance ToJSON a => ToJSON (Dual a) where
+    toJSON = toJSON . getDual
+    {-# INLINE toJSON #-}
+
+instance FromJSON a => FromJSON (Dual a) where
+    parseJSON = fmap Dual . parseJSON
+    {-# INLINE parseJSON #-}
+
+instance ToJSON a => ToJSON (First a) where
+    toJSON = toJSON . getFirst
+    {-# INLINE toJSON #-}
+
+instance FromJSON a => FromJSON (First a) where
+    parseJSON = fmap First . parseJSON
+    {-# INLINE parseJSON #-}
+
+instance ToJSON a => ToJSON (Last a) where
+    toJSON = toJSON . getLast
+    {-# INLINE toJSON #-}
+
+instance FromJSON a => FromJSON (Last a) where
+    parseJSON = fmap Last . parseJSON
+    {-# INLINE parseJSON #-}
+
+-- | @withObject expected f value@ applies @f@ to the 'Object' when @value@ is an @Object@
+--   and fails using @'typeMismatch' expected@ otherwise.
+withObject :: String -> (Object -> Parser a) -> Value -> Parser a
+withObject _        f (Object obj) = f obj
+withObject expected _ v            = typeMismatch expected v
+{-# INLINE withObject #-}
+
+-- | @withText expected f value@ applies @f@ to the 'Text' when @value@ is a @String@
+--   and fails using @'typeMismatch' expected@ otherwise.
+withText :: String -> (Text -> Parser a) -> Value -> Parser a
+withText _        f (String txt) = f txt
+withText expected _ v            = typeMismatch expected v
+{-# INLINE withText #-}
+
+-- | @withArray expected f value@ applies @f@ to the 'Array' when @value@ is an @Array@
+--   and fails using @'typeMismatch' expected@ otherwise.
+withArray :: String -> (Array -> Parser a) -> Value -> Parser a
+withArray _        f (Array arr) = f arr
+withArray expected _ v           = typeMismatch expected v
+{-# INLINE withArray #-}
+
+-- | @withNumber expected f value@ applies @f@ to the 'Number' when @value@ is a 'Number'.
+--   and fails using @'typeMismatch' expected@ otherwise.
+withNumber :: String -> (Number -> Parser a) -> Value -> Parser a
+withNumber expected f = withScientific expected (f . scientificToNumber)
+{-# INLINE withNumber #-}
+{-# DEPRECATED withNumber "Use withScientific instead" #-}
+
+-- | @withScientific expected f value@ applies @f@ to the 'Scientific' number when @value@ is a 'Number'.
+--   and fails using @'typeMismatch' expected@ otherwise.
+withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
+withScientific _        f (Number scientific) = f scientific
+withScientific expected _ v                   = typeMismatch expected v
+{-# INLINE withScientific #-}
+
+-- | @withBool expected f value@ applies @f@ to the 'Bool' when @value@ is a @Bool@
+--   and fails using @'typeMismatch' expected@ otherwise.
+withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
+withBool _        f (Bool arr) = f arr
+withBool expected _ v          = typeMismatch expected v
+{-# INLINE withBool #-}
+
+-- | Construct a 'Pair' from a key and a value.
+(.=) :: ToJSON a => Text -> a -> Pair
+name .= value = (name, toJSON value)
+{-# INLINE (.=) #-}
+
+-- | Convert a value from JSON, failing if the types do not match.
+fromJSON :: (FromJSON a) => Value -> Result a
+fromJSON = parse parseJSON
+{-# INLINE fromJSON #-}
+
+-- | Retrieve the value associated with the given key of an 'Object'.
+-- The result is 'empty' if the key is not present or the value cannot
+-- be converted to the desired type.
+--
+-- This accessor is appropriate if the key and value /must/ be present
+-- in an object for it to be valid.  If the key and value are
+-- optional, use '(.:?)' instead.
+(.:) :: (FromJSON a) => Object -> Text -> Parser a
+obj .: key = case H.lookup key obj of
+               Nothing -> fail $ "key " ++ show key ++ " not present"
+               Just v  -> parseJSON v
+{-# INLINE (.:) #-}
+
+-- | Retrieve the value associated with the given key of an 'Object'.
+-- The result is 'Nothing' if the key is not present, or 'empty' if
+-- the value cannot be converted to the desired type.
+--
+-- This accessor is most useful if the key and value can be absent
+-- from an object without affecting its validity.  If the key and
+-- value are mandatory, use '(.:)' instead.
+(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
+obj .:? key = case H.lookup key obj of
+               Nothing -> pure Nothing
+               Just v  -> parseJSON v
+{-# INLINE (.:?) #-}
+
+-- | Helper for use in combination with '.:?' to provide default
+-- values for optional JSON object fields.
+--
+-- This combinator is most useful if the key and value can be absent
+-- from an object without affecting its validity and we know a default
+-- value to assign in that case.  If the key and value are mandatory,
+-- use '(.:)' instead.
+--
+-- Example usage:
+--
+-- @ v1 <- o '.:?' \"opt_field_with_dfl\" .!= \"default_val\"
+-- v2 <- o '.:'  \"mandatory_field\"
+-- v3 <- o '.:?' \"opt_field2\"
+-- @
+(.!=) :: Parser (Maybe a) -> a -> Parser a
+pmval .!= val = fromMaybe val <$> pmval
+{-# INLINE (.!=) #-}
+
+-- | Fail parsing due to a type mismatch, with a descriptive message.
+typeMismatch :: String -- ^ The name of the type you are trying to parse.
+             -> Value  -- ^ The actual value encountered.
+             -> Parser a
+typeMismatch expected actual =
+    fail $ "when expecting a " ++ expected ++ ", encountered " ++ name ++
+           " instead"
+  where
+    name = case actual of
+             Object _ -> "Object"
+             Array _  -> "Array"
+             String _ -> "String"
+             Number _ -> "Number"
+             Bool _   -> "Boolean"
+             Null     -> "Null"
+
+scientificToNumber :: Scientific -> Number
+scientificToNumber s
+    | e < 0     = D $ realToFrac s
+    | otherwise = I $ c * 10 ^ e
+  where
+    e = Scientific.base10Exponent s
+    c = Scientific.coefficient s
+{-# INLINE scientificToNumber #-}
diff --git a/Data/Aeson/Types/Internal.hs b/Data/Aeson/Types/Internal.hs
--- a/Data/Aeson/Types/Internal.hs
+++ b/Data/Aeson/Types/Internal.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, DeriveDataTypeable, Rank2Types #-}
+{-# LANGUAGE CPP, DeriveDataTypeable, GeneralizedNewtypeDeriving, Rank2Types #-}
 
 -- |
 -- Module:      Data.Aeson.Types.Internal
@@ -35,17 +35,28 @@
     , SumEncoding(..)
     , defaultOptions
     , defaultTaggedObject
+
+    -- * Used for changing CamelCase names into something else.
+    , camelTo
+
+    -- * Other types
+    , DotNetTime(..)
     ) where
 
+
 import Control.Applicative
 import Control.Monad
 import Control.DeepSeq (NFData(..))
-import Data.Attoparsec.Char8 (Number(..))
+import Data.Char (toLower, isUpper)
+import Data.Scientific (Scientific)
 import Data.Hashable (Hashable(..))
+import Data.Data (Data)
 import Data.HashMap.Strict (HashMap)
 import Data.Monoid (Monoid(..))
 import Data.String (IsString(..))
 import Data.Text (Text, pack)
+import Data.Time (UTCTime)
+import Data.Time.Format (FormatTime)
 import Data.Typeable (Typeable)
 import Data.Vector (Vector)
 import qualified Data.HashMap.Strict as H
@@ -166,16 +177,27 @@
 data Value = Object !Object
            | Array !Array
            | String !Text
-           | Number !Number
+           | Number !Scientific
            | Bool !Bool
            | Null
-             deriving (Eq, Show, Typeable)
+             deriving (Eq, Show, Typeable, Data)
 
+-- | A newtype wrapper for 'UTCTime' that uses the same non-standard
+-- serialization format as Microsoft .NET, whose @System.DateTime@
+-- type is by default serialized to JSON as in the following example:
+--
+-- > /Date(1302547608878)/
+--
+-- The number represents milliseconds since the Unix epoch.
+newtype DotNetTime = DotNetTime {
+      fromDotNetTime :: UTCTime
+    } deriving (Eq, Ord, Read, Show, Typeable, FormatTime)
+
 instance NFData Value where
     rnf (Object o) = rnf o
     rnf (Array a)  = V.foldl' (\x y -> rnf y `seq` x) () a
     rnf (String s) = rnf s
-    rnf (Number n) = case n of I i -> rnf i; D d -> rnf d
+    rnf (Number n) = rnf n
     rnf (Bool b)   = rnf b
     rnf Null       = ()
 
@@ -183,17 +205,18 @@
     fromString = String . pack
     {-# INLINE fromString #-}
 
+hashValue :: Int -> Value -> Int
+hashValue s (Object o)   = H.foldl' hashWithSalt
+                              (s `hashWithSalt` (0::Int)) o
+hashValue s (Array a)    = V.foldl' hashWithSalt
+                              (s `hashWithSalt` (1::Int)) a
+hashValue s (String str) = s `hashWithSalt` (2::Int) `hashWithSalt` str
+hashValue s (Number n)   = s `hashWithSalt` (3::Int) `hashWithSalt` n
+hashValue s (Bool b)     = s `hashWithSalt` (4::Int) `hashWithSalt` b
+hashValue s Null         = s `hashWithSalt` (5::Int)
+
 instance Hashable Value where
-    hashWithSalt s (Object o)   = H.foldl' hashWithSalt
-                                  (s `hashWithSalt` (0::Int)) o
-    hashWithSalt s (Array a)    = V.foldl' hashWithSalt
-                                  (s `hashWithSalt` (1::Int)) a
-    hashWithSalt s (String str) = s `hashWithSalt` (2::Int) `hashWithSalt` str
-    hashWithSalt s (Number n)   = 3 `hashWithSalt`
-                                  case n of I i -> hashWithSalt s i
-                                            D d -> hashWithSalt s d
-    hashWithSalt s (Bool b)   = s `hashWithSalt` (4::Int) `hashWithSalt` b
-    hashWithSalt s Null       = s `hashWithSalt` (5::Int)
+    hashWithSalt = hashValue
 
 -- | The empty array.
 emptyArray :: Value
@@ -328,3 +351,24 @@
                       { tagFieldName      = "tag"
                       , contentsFieldName = "contents"
                       }
+
+-- | Converts from CamelCase to another lower case, interspersing
+--   the character between all capital letters and their previous
+--   entries, except those capital letters that appear together,
+--   like 'API'.
+--
+--   For use by Aeson template haskell calls.
+--
+--   > camelTo '_' 'CamelCaseAPI' == "camel_case_api"
+camelTo :: Char -> String -> String
+camelTo c = lastWasCap True
+  where
+    lastWasCap :: Bool    -- ^ Previous was a capital letter
+              -> String  -- ^ The remaining string
+              -> String
+    lastWasCap _    []           = []
+    lastWasCap prev (x : xs)     = if isUpper x
+                                      then if prev
+                                             then toLower x : lastWasCap True xs
+                                             else c : toLower x : lastWasCap True xs
+                                      else x : lastWasCap False xs
diff --git a/aeson.cabal b/aeson.cabal
--- a/aeson.cabal
+++ b/aeson.cabal
@@ -1,5 +1,5 @@
 name:            aeson
-version:         0.6.2.1
+version:         0.7.0.0
 license:         BSD3
 license-file:    LICENSE
 category:        Text, Web, JSON
@@ -8,7 +8,7 @@
 author:          Bryan O'Sullivan <bos@serpentine.com>
 maintainer:      Bryan O'Sullivan <bos@serpentine.com>
 stability:       experimental
-tested-with:     GHC == 6.12.3, GHC == 7.0.4, GHC == 7.2.2
+tested-with:     GHC == 7.0, GHC == 7.2, GHC == 7.4, GHC == 7.6
 synopsis:        Fast JSON parsing and encoding
 cabal-version:   >= 1.8
 homepage:        https://github.com/bos/aeson
@@ -21,59 +21,41 @@
     To get started, see the documentation for the @Data.Aeson@ module
     below.
     .
-    For release notes, see
-    <https://github.com/bos/aeson/blob/master/release-notes.markdown>
-    .
-    Parsing performance on a late 2010 MacBook Pro (2.66GHz Core i7),
-    for mostly-English tweets from Twitter's JSON search API:
-    .
-    * 0.8 KB, 32-bit GHC 6.12.3: 30538 msg\/sec (24.9 MB\/sec)
-    .
-    * 0.8 KB, 64-bit GHC 7.0.3: 31204 msg\/sec (25.4 MB\/sec)
-    .
-    * 6.4 KB, 32-bit GHC 6.12.3: 6731 msg\/sec (42.3 MB\/sec)
-    .
-    * 6.4 KB, 64-bit GHC 7.0.3: 6627 msg\/sec (41.7 MB\/sec)
-    .
-    * 11.8 KB, 32-bit GHC 6.12.3: 3751 msg\/sec (43.2 MB\/sec)
+    Parsing performance on an early 2011 MacBook Pro (2.2GHz Core i7),
+    running 64-bit GHC 7.6.3, for mostly-English tweets from Twitter's
+    JSON search API:
     .
-    * 11.8 KB, 64-bit GHC 7.0.3: 3381 msg\/sec (38.9 MB\/sec)
+    * 0.8 KB: 34124 msg\/sec (27.8 MB\/sec)
     .
-    * 31.2 KB, 32-bit GHC 6.12.3: 1306 msg\/sec (39.8 MB\/sec)
+    * 6.4 KB: 6833 msg\/sec (43.0 MB\/sec)
     .
-    * 31.2 KB, 64-bit GHC 7.0.3: 1132 msg\/sec (34.5 MB\/sec)
+    * 11.8 KB: 3410 msg\/sec (39.2 MB\/sec)
     .
-    * 61.5 KB, 32-bit GHC 6.12.3: 616 msg\/sec (37.0 MB\/sec)
+    * 31.2 KB: 1157 msg\/sec (35.3 MB\/sec)
     .
-    * 61.5 KB, 64-bit GHC 7.0.3: 534 msg\/sec (32.1 MB\/sec)
+    * 61.5 KB: 542 msg\/sec (32.5 MB\/sec)
     .
     Handling heavily-escaped text is a little more work.  Here is
     parsing performance with Japanese tweets, where much of the text
     is entirely Unicode-escaped.
     .
-    * 14.6 KB, 32-bit GHC 6.12.3: 2315 msg\/sec (33.1 MB\/sec)
-    .
-    * 14.6 KB, 64-bit GHC 7.0.3: 1986 msg\/sec (28.4 MB\/sec)
-    .
-    * 44.1 KB, 32-bit GHC 6.12.3: 712 msg\/sec (30.7 MB\/sec)
-    .
-    * 44.1 KB, 64-bit GHC 7.0.3: 634 msg\/sec (27.3 MB\/sec)
+    * 14.6 KB: 2101 msg\/sec (30.0 MB\/sec)
     .
-    * 82.9 KB, 32-bit GHC 6.12.3: 377 msg\/sec (30.5 MB\/sec)
+    * 44.1 KB: 667 msg\/sec (28.7 MB\/sec)
     .
-    * 82.9 KB, 64-bit GHC 7.0.3: 332 msg\/sec (26.9 MB\/sec)
+    * 82.9 KB: 360 msg\/sec (29.2 MB\/sec)
     .
     Encoding performance on the same machine and data:
     .
-    * English, 854 bytes: 43439 msg\/sec (35.4 MB/sec)
+    * English, 0.8 KB: 109697 msg\/sec (89.3 MB\/sec)
     .
-    * English, 6.4 KB: 7127 msg\/sec (44.8 MB/sec)
+    * English, 6.4 KB: 18517 msg\/sec (116.4 MB\/sec)
     .
-    * Engish, 61.5 KB: 765 msg\/sec (46.0 MB/sec)
+    * Engish, 61.5 KB: 1963 msg\/sec (118.0 MB\/sec)
     .
-    * Japanese, 14.6 KB: 4727 msg\/sec (67.5 MB/sec)
+    * Japanese, 14.6 KB: 12140 msg\/sec (173.5 MB\/sec)
     .
-    * Japanese, 44.1 KB: 1505 msg\/sec (64.8 MB/sec)
+    * Japanese, 44.1 KB: 3980 msg\/sec (171.3 MB\/sec)
     .
     (A note on naming: in Greek mythology, Aeson was the father of Jason.)
 
@@ -84,13 +66,21 @@
     benchmarks/*.py
     benchmarks/Makefile
     benchmarks/json-data/*.json
+    changelog
     examples/*.hs
-    release-notes.markdown
 
 flag developer
   description: operate in developer mode
   default: False
 
+flag blaze-builder
+  description: Use blaze-builder instead of bytestring >= 0.10
+  default: False
+
+flag new-bytestring-builder
+  description: Use the new bytestring builder available in bytestring >= 0.10.4.0
+  default: False
+
 library
   exposed-modules:
     Data.Aeson
@@ -104,8 +94,17 @@
     Data.Aeson.Functions
     Data.Aeson.Parser.Internal
     Data.Aeson.Types.Class
+    Data.Aeson.Types.Instances
     Data.Aeson.Types.Internal
 
+  if flag(new-bytestring-builder)
+    other-modules: Data.Aeson.Encode.ByteString
+    build-depends: bytestring >= 0.10.4.0,
+                   text >= 1.1.0.0
+  else
+    build-depends: bytestring < 0.10.4.0,
+                   text >= 0.11.1.0
+
   if impl(ghc >= 7.2.1)
     cpp-options: -DGENERICS
     build-depends: ghc-prim >= 0.2, dlist >= 0.2
@@ -113,10 +112,8 @@
       Data.Aeson.Types.Generic
 
   build-depends:
-    attoparsec >= 0.8.6.1,
+    attoparsec >= 0.11.1.0,
     base == 4.*,
-    blaze-builder >= 0.2.1.4,
-    bytestring,
     containers,
     deepseq,
     hashable >= 1.1.2.0,
@@ -124,11 +121,17 @@
     old-locale,
     syb,
     template-haskell >= 2.4,
-    text >= 0.11.1.0,
     time,
     unordered-containers >= 0.1.3.0,
-    vector >= 0.7.1
+    vector >= 0.7.1,
+    scientific >= 0.2
 
+  if flag(blaze-builder)
+    build-depends: blaze-builder >= 0.2.1.4
+    cpp-options: -DUSE_BLAZE_BUILDER
+  else
+    build-depends: bytestring >= 0.10
+
   if flag(developer)
     ghc-options: -Werror
     ghc-prof-options: -auto-all
@@ -139,12 +142,13 @@
   type:           exitcode-stdio-1.0
   hs-source-dirs: tests
   main-is:        Properties.hs
-  other-modules:  Functions
-                  Instances
-                  Types
-                  Options
-                  Encoders
-                  Properties.Deprecated
+  other-modules:
+    Encoders
+    Functions
+    Instances
+    Options
+    Properties.Deprecated
+    Types
 
   ghc-options:
     -Wall -threaded -rtsopts
@@ -163,6 +167,8 @@
     template-haskell,
     test-framework,
     test-framework-quickcheck2,
+    test-framework-hunit,
+    HUnit,
     text,
     time,
     unordered-containers,
diff --git a/benchmarks/AesonEncode.hs b/benchmarks/AesonEncode.hs
--- a/benchmarks/AesonEncode.hs
+++ b/benchmarks/AesonEncode.hs
@@ -3,7 +3,8 @@
 import Control.Exception
 import Control.Monad
 import Data.Aeson
-import Data.Attoparsec
+import Data.Attoparsec (IResult(..), parseWith)
+import Data.Char (isDigit)
 import Data.Time.Clock
 import System.Environment (getArgs)
 import System.IO
@@ -22,7 +23,10 @@
 
 main :: IO ()
 main = do
-  (cnt:args) <- getArgs
+  args0 <- getArgs
+  let (cnt,args) = case args0 of
+        (i:c:a) | all isDigit i && all isDigit c -> (c,a)
+        (c:a) -> (c,a)
   let count = read cnt :: Int
   forM_ args $ \arg -> bracket (openFile arg ReadMode) hClose $ \h -> do
     putStrLn $ arg ++ ":"
@@ -39,5 +43,5 @@
     loop 0 r0
     delta <- flip diffUTCTime start `fmap` getCurrentTime
     let rate = fromIntegral count / realToFrac delta :: Double
-    putStrLn $ "  " ++ show delta
+    putStrLn $ "  " ++ cnt ++ " good, " ++ show delta
     putStrLn $ "  " ++ show (round rate :: Int) ++ " per second"
diff --git a/benchmarks/AesonParse.hs b/benchmarks/AesonParse.hs
--- a/benchmarks/AesonParse.hs
+++ b/benchmarks/AesonParse.hs
@@ -3,12 +3,13 @@
 import Control.Exception
 import Control.Monad
 import Data.Aeson
-import Data.Attoparsec
+import Data.Attoparsec (IResult(..), parseWith)
 import Data.Time.Clock
 import System.Environment (getArgs)
 import System.IO
 import qualified Data.ByteString as B
 
+main :: IO ()
 main = do
   (bs:cnt:args) <- getArgs
   let count = read cnt :: Int
@@ -23,10 +24,10 @@
           let refill = B.hGet h blkSize
           result <- parseWith refill json =<< refill
           case result of
-            Done _ r -> loop (good+1) bad
+            Done _ _ -> loop (good+1) bad
             _        -> loop good (bad+1)
     (good, _) <- loop 0 0
     delta <- flip diffUTCTime start `fmap` getCurrentTime
     putStrLn $ "  " ++ show good ++ " good, " ++ show delta
     let rate = fromIntegral count / realToFrac delta :: Double
-    putStrLn $ "  " ++ show (round rate) ++ " per second"
+    putStrLn $ "  " ++ show (round rate :: Int) ++ " per second"
diff --git a/benchmarks/CompareWithJSON.hs b/benchmarks/CompareWithJSON.hs
--- a/benchmarks/CompareWithJSON.hs
+++ b/benchmarks/CompareWithJSON.hs
@@ -5,9 +5,13 @@
 import Blaze.ByteString.Builder.Char.Utf8 (fromString)
 import Control.DeepSeq (NFData(rnf))
 import Criterion.Main
+import qualified Data.Aeson.Encode as A
 import qualified Data.Aeson as A
 import qualified Data.ByteString.Lazy as BL
 import qualified Text.JSON as J
+import qualified Data.Text.Lazy          as TL
+import qualified Data.Text.Lazy.Builder  as TLB
+import qualified Data.Text.Lazy.Encoding as TLE
 
 #if !MIN_VERSION_bytestring(0,10,0)
 import qualified Data.ByteString.Lazy.Internal as BL
@@ -42,6 +46,14 @@
 encodeJ :: J.JSValue -> BL.ByteString
 encodeJ = toLazyByteString . fromString . J.encode
 
+#if MIN_VERSION_bytestring(0,10,4)
+encodeToText :: A.Value -> TL.Text
+encodeToText = TLB.toLazyText . A.encodeToTextBuilder . A.toJSON
+
+encodeViaText :: A.Value -> BL.ByteString
+encodeViaText = TLE.encodeUtf8 . encodeToText
+#endif
+
 main :: IO ()
 main = do
   let enFile = "json-data/twitter100.json"
@@ -63,11 +75,19 @@
       ]
     , bgroup "encode" [
         bgroup "en" [
-          bench "aeson" $ nf A.encode (decodeA enA)
+          bench "aeson-to-bytestring" $ nf A.encode (decodeA enA)
+#if MIN_VERSION_bytestring(0,10,4)
+        , bench "aeson-via-text-to-bytestring" $ nf encodeViaText (decodeA enA)
+        , bench "aeson-to-text" $ nf encodeToText (decodeA enA)
+#endif
         , bench "json"  $ nf encodeJ (decodeJ enJ)
         ]
       , bgroup "jp" [
-          bench "aeson" $ nf A.encode (decodeA jpA)
+          bench "aeson-to-bytestring" $ nf A.encode (decodeA jpA)
+#if MIN_VERSION_bytestring(0,10,4)
+        , bench "aeson-via-text-to-bytestring" $ nf encodeViaText (decodeA jpA)
+        , bench "aeson-to-text" $ nf encodeToText (decodeA jpA)
+#endif
         , bench "json"  $ nf encodeJ (decodeJ jpJ)
         ]
       ]
diff --git a/benchmarks/JsonParse.hs b/benchmarks/JsonParse.hs
--- a/benchmarks/JsonParse.hs
+++ b/benchmarks/JsonParse.hs
@@ -6,7 +6,6 @@
 import Text.JSON
 import Data.Time.Clock
 import System.Environment (getArgs)
-import System.IO
 
 instance NFData JSValue where
     rnf JSNull = ()
@@ -16,6 +15,7 @@
     rnf (JSArray vs) = rnf vs
     rnf (JSObject kvs) = rnf (fromJSObject kvs)
 
+main :: IO ()
 main = do
   (cnt:args) <- getArgs
   let count = read cnt :: Int
@@ -27,7 +27,7 @@
             | otherwise = do
           s <- readFile arg
           case decodeStrict s of
-            Ok (v::JSValue) -> loop (good+1) 0
+            Ok (_::JSValue) -> loop (good+1) 0
             _ -> loop 0 (bad+1)
     (good, _) <- loop 0 0
     end <- getCurrentTime
diff --git a/benchmarks/aeson-benchmarks.cabal b/benchmarks/aeson-benchmarks.cabal
--- a/benchmarks/aeson-benchmarks.cabal
+++ b/benchmarks/aeson-benchmarks.cabal
@@ -6,25 +6,26 @@
 
 executable aeson-benchmark-compare-with-json
   main-is: CompareWithJSON.hs
-  ghc-options: -Wall -O2
+  ghc-options: -Wall -O2 -rtsopts
   build-depends:
     aeson,
     base,
     blaze-builder,
     bytestring,
     criterion,
-    json
+    json,
+    text
 
 executable aeson-benchmark-aeson-encode
   main-is: AesonEncode.hs
-  ghc-options: -Wall -O2
+  ghc-options: -Wall -O2 -rtsopts
   build-depends:
     aeson,
     base
 
 executable aeson-benchmark-aeson-parse
   main-is: AesonParse.hs
-  ghc-options: -Wall -O2
+  ghc-options: -Wall -O2 -rtsopts
   build-depends:
     aeson,
     attoparsec,
@@ -32,7 +33,7 @@
 
 executable aeson-benchmark-json-parse
   main-is: JsonParse.hs
-  ghc-options: -Wall -O2
+  ghc-options: -Wall -O2 -rtsopts
   build-depends:
     base,
     deepseq,
diff --git a/benchmarks/bench-parse.py b/benchmarks/bench-parse.py
--- a/benchmarks/bench-parse.py
+++ b/benchmarks/bench-parse.py
@@ -7,11 +7,12 @@
 if len(sys.argv) > 1:
     parser_exe = sys.argv[1]
 else:
-    parser_exe = './AesonParse'
+    parser_exe = ('dist/build/aeson-benchmark-aeson-parse/' +
+                  'aeson-benchmark-aeson-parse')
 
 def run(count, filename):
     print '    %s :: %s times' % (filename, count)
-    p = subprocess.Popen([parser_exe, str(count), filename],
+    p = subprocess.Popen([parser_exe, '65536', str(count), filename],
                          stdout=subprocess.PIPE)
     output = p.stdout.read()
     p.wait()
diff --git a/benchmarks/encode.py b/benchmarks/encode.py
--- a/benchmarks/encode.py
+++ b/benchmarks/encode.py
@@ -2,6 +2,16 @@
 
 import json, sys, time
 
+def isint(x):
+    try:
+        int(x)
+        return True
+    except:
+        return False
+
+if len(sys.argv) > 2 and isint(sys.argv[1]) and isint(sys.argv[2]):
+    sys.argv.pop(1)
+
 count = int(sys.argv[1])
 
 for n in sys.argv[2:]:
@@ -11,4 +21,4 @@
     for i in xrange(count):
         json.dumps(obj)
     end = time.time()
-    print ' ', end - start
+    print '  %d good, %gs' % (count, end - start)
diff --git a/benchmarks/json-data/geometry.json b/benchmarks/json-data/geometry.json
new file mode 100644
--- /dev/null
+++ b/benchmarks/json-data/geometry.json
@@ -0,0 +1,1 @@
+{"geometry": {"type": "Polygon", "coordinates": [[[-0.939359853061118, 51.57401065198471], [-0.939440892477492, 51.57431080772057], [-0.939543636564569, 51.57460846194951], [-0.939564627628489, 51.574822653966265], [-0.939763179055758, 51.575406210178826], [-0.939787182642249, 51.575552991614], [-0.939819571231525, 51.57564949527348], [-0.939851290904264, 51.57571272360808], [-0.939975682132949, 51.57588648747347], [-0.940036822193859, 51.57598774653439], [-0.940072640734852, 51.57606090267849], [-0.940109693338918, 51.576205104339515], [-0.940125502187331, 51.57645611534466], [-0.940118623499009, 51.57662779459441], [-0.94008851367835, 51.57680555827417], [-0.939998015208524, 51.57709787034017], [-0.939928028667517, 51.577252794653916], [-0.939830628174189, 51.57740747134858], [-0.939796941313687, 51.57749078985784], [-0.939785586773343, 51.57754463746666], [-0.939770656147318, 51.57769016804059], [-0.939658154074368, 51.57824573765943], [-0.939485738834128, 51.57883313597966], [-0.93945717030888, 51.579192545519916], [-0.939524336079755, 51.57928306919007], [-0.939540939284811, 51.57931379092206], [-0.939553921057406, 51.579748206813974], [-0.939549110634237, 51.57983088690364], [-0.939520940649101, 51.58004913048237], [-0.93951863934971, 51.58014801827346], [-0.939525037302583, 51.580245186310094], [-0.939540364690294, 51.58033074581249], [-0.939561798495469, 51.58040197377017], [-0.939594984852117, 51.58046431619436], [-0.939708262827559, 51.580619996404984], [-0.939729069878358, 51.58065615108302], [-0.939759224390201, 51.58072476025555], [-0.939813615319267, 51.58093026195459], [-0.939900523550716, 51.58172321441459], [-0.939894144544868, 51.581997403240464], [-0.939910832471369, 51.58208657162566], [-0.940114353648015, 51.582457967531546], [-0.94022333049887, 51.58267475179605], [-0.940267247821581, 51.58277225843995], [-0.94038427828014, 51.583077233742756], [-0.940493362377966, 51.583289522851196], [-0.940571515796737, 51.58340442254201], [-0.940725857371931, 51.58359464061899], [-0.941198340240742, 51.584069167875626], [-0.941335307610427, 51.584261925920295], [-0.941372786463165, 51.5843261048293], [-0.941416540699353, 51.58443080287741], [-0.941461326187118, 51.584739621364996], [-0.941517445876004, 51.5849954910945], [-0.941575869597484, 51.58533860085252], [-0.941574762730556, 51.58538624677686], [-0.941565185406358, 51.58542572382202], [-0.941550002863301, 51.58545795698674], [-0.941515976834126, 51.58549361692739], [-0.941470510606583, 51.585524677868065], [-0.941423872780384, 51.585544039043356], [-0.94131509921043, 51.585566436558274], [-0.941075026707647, 51.58558675057684], [-0.940953181611661, 51.58561262652464], [-0.940734943851404, 51.58568708689612], [-0.940229533088359, 51.585883040066975], [-0.940067635923264, 51.58595531027499], [-0.939917220191166, 51.58603038143916], [-0.939797255285709, 51.586099433232604], [-0.939675637701456, 51.586177461657186], [-0.939611074554604, 51.58622273608784], [-0.939340396866166, 51.586441486256], [-0.93912244296424, 51.58662744303347], [-0.938817233975319, 51.58671729893312], [-0.938661522913105, 51.586771639765516], [-0.938087678078033, 51.586992141762096], [-0.937332636663603, 51.5873072119485], [-0.93492634290483, 51.58836081134952], [-0.934774110277819, 51.58845114531925], [-0.934663126573178, 51.588505886685766], [-0.934565467487243, 51.588546362183585], [-0.934462140700832, 51.588582290320545], [-0.934337145222589, 51.58861892084846], [-0.934213782000904, 51.588647473549656], [-0.934055887760941, 51.588671216763295], [-0.933259701136762, 51.58864510257983], [-0.933213278816969, 51.588716614209304], [-0.932681740160827, 51.588792708227174], [-0.931992471253759, 51.58900853446031], [-0.930629113767652, 51.58946908647644], [-0.928525036745892, 51.59005953842682], [-0.928533690860491, 51.59024394687689], [-0.928456010745829, 51.59047792078815], [-0.928256501298223, 51.5906748158337], [-0.927916132025856, 51.59066181734799], [-0.927671608556404, 51.590624516635486], [-0.927319567022116, 51.59061680481465], [-0.926850285435352, 51.59062240702726], [-0.926313746570405, 51.59066425819173], [-0.925516790702947, 51.59079184232522], [-0.925387133168341, 51.59078076476673], [-0.925293323156809, 51.59077990606886], [-0.925202187496562, 51.59078806346173], [-0.925112304116411, 51.59080432476366], [-0.925036768134577, 51.59082431403807], [-0.924968299737815, 51.59085066215826], [-0.924899640304234, 51.59088510100373], [-0.924851228495836, 51.590917926896914], [-0.924734051019008, 51.59105082982951], [-0.924694255912291, 51.59108553291224], [-0.924446018071168, 51.59126668934789], [-0.924204972773907, 51.59150995377465], [-0.923492520665307, 51.59215352189589], [-0.922775141969353, 51.59288246146081], [-0.922298613651092, 51.59343737077436], [-0.922101568270595, 51.59365046303728], [-0.92149319027045, 51.59422483935332], [-0.921029930136652, 51.59464499018023], [-0.919455791303858, 51.595519790418045], [-0.919908472816787, 51.59560757835559], [-0.919902358174605, 51.595621908790214], [-0.919721503870405, 51.59588190272939], [-0.919513222918683, 51.59614164398608], [-0.919057326435374, 51.59661490568889], [-0.918991959815932, 51.59669253146064], [-0.918853979663433, 51.59690975873926], [-0.91882720841051, 51.59694278142396], [-0.918711889332325, 51.597056812913756], [-0.918614808732714, 51.59713234806153], [-0.918297245740306, 51.59749448485627], [-0.918073703114389, 51.59778825130676], [-0.917853804369843, 51.59811082427763], [-0.917772408698363, 51.59831598343439], [-0.917709563771812, 51.59853030520902], [-0.917692745480418, 51.59856971355161], [-0.917634249201942, 51.59866178857289], [-0.917443039919903, 51.59887043094418], [-0.917335250471836, 51.598971042984616], [-0.916888284039272, 51.599309503426845], [-0.916921110547038, 51.59938623548714], [-0.916942485633783, 51.5995195094582], [-0.916937652924948, 51.599601289122916], [-0.916945811778801, 51.599683188627004], [-0.916964246289877, 51.599757989575366], [-0.917049297107238, 51.59994580090974], [-0.917089705367533, 51.60000731699611], [-0.917171120773417, 51.60010517795964], [-0.91752823274465, 51.60044925531009], [-0.917834023417531, 51.600765883511485], [-0.917913079603466, 51.600902386385464], [-0.918033251654948, 51.60107073894696], [-0.91851090277833, 51.601507638962644], [-0.918694916056997, 51.601663091331545], [-0.919167224655989, 51.60214309940451], [-0.919302231291783, 51.6024167896932], [-0.919552009673002, 51.60266096432073], [-0.919812571846437, 51.60293760761218], [-0.920091738726093, 51.60358667644501], [-0.920208566517809, 51.603592246724574], [-0.920644522919282, 51.60359715428394], [-0.921093152621479, 51.6036156641763], [-0.921168285587618, 51.603613657034074], [-0.921469264587163, 51.6035867495928], [-0.921584776688781, 51.603586911416876], [-0.921718864440287, 51.603595336217005], [-0.921999521996191, 51.60363387995426], [-0.922136050325758, 51.603661209181794], [-0.922248015684399, 51.60368921195661], [-0.922346882036963, 51.60372159023333], [-0.922478548042792, 51.60377135359644], [-0.922605777045377, 51.603825571929555], [-0.92269948345521, 51.60389297005248], [-0.922855181916126, 51.60396453348124], [-0.922908065211369, 51.60398749776935], [-0.923525984356841, 51.604174796116844], [-0.923689774691443, 51.6042095667925], [-0.923842334751645, 51.60423074681459], [-0.924020987014581, 51.604247669912816], [-0.924152253615336, 51.604253368572344], [-0.924379056519158, 51.60424915231234], [-0.924491916632975, 51.60423939614583], [-0.925129396784027, 51.604149022807746], [-0.925308707040747, 51.60413807581467], [-0.925396812395019, 51.604137083863186], [-0.925816640142735, 51.60415261457396], [-0.926339243350925, 51.604157394450915], [-0.926627592983669, 51.60417621577326], [-0.928219342008724, 51.60433911850777], [-0.928540897883304, 51.60435823822504], [-0.928666454251138, 51.6043611822271], [-0.928925123731038, 51.60435275210506], [-0.929272427371303, 51.60432085222454], [-0.929350681081097, 51.604308977474346], [-0.929525019586135, 51.60426381040009], [-0.929730308556221, 51.60419195021111], [-0.929806393059037, 51.60414948374236], [-0.929854111423592, 51.60408517871234], [-0.929877477717563, 51.604012559228565], [-0.929880189120251, 51.60395863398061], [-0.930157001898001, 51.603362311928585], [-0.930233415197893, 51.60324431822904], [-0.930397156019029, 51.60303540508514], [-0.93058677482955, 51.602831223239896], [-0.930747612253953, 51.60268432562219], [-0.931065151604954, 51.602443542878724], [-0.931358556224333, 51.60224659876122], [-0.931494751600125, 51.602165114969594], [-0.931807666849096, 51.601998019766675], [-0.932115553298882, 51.60186055047904], [-0.932344261944379, 51.601774512081256], [-0.932581062209752, 51.601712824287226], [-0.932837650566022, 51.60166929919289], [-0.93304760157037, 51.60164423223924], [-0.933247236692325, 51.60162806284857], [-0.933524572231589, 51.601623388892406], [-0.93367307135076, 51.60163283011416], [-0.933854562367985, 51.601651562386515], [-0.934222940436163, 51.60170526005669], [-0.934582321335698, 51.60177326158339], [-0.935176916778695, 51.60190903449902], [-0.935323237909383, 51.60194992468383], [-0.935449328012611, 51.60199153042619], [-0.935555166022244, 51.60203475076641], [-0.935754957696255, 51.60213547009268], [-0.935920944220561, 51.60219991608389], [-0.936105992086264, 51.60225194623237], [-0.936251123590137, 51.60228203448254], [-0.9362553703842, 51.602285669620606], [-0.935954861941404, 51.603034649313756], [-0.936025513047831, 51.60328615677915], [-0.937604653681525, 51.60374194595848], [-0.937842729718605, 51.6037494948452], [-0.937998245297976, 51.60376798569096], [-0.938149157504488, 51.60379812385097], [-0.938282536474463, 51.60383709493093], [-0.938398403200176, 51.60388400001471], [-0.938549544157173, 51.60396629131982], [-0.938542113846477, 51.60403725821696], [-0.938540670189083, 51.60403724516617], [-0.938690470772444, 51.60417707075241], [-0.93885671831091, 51.60429276731543], [-0.938949655717409, 51.60433227129961], [-0.939171393952754, 51.60435945147724], [-0.939491406642938, 51.60438302306183], [-0.939580914110842, 51.60438383145672], [-0.939698081584302, 51.604374998744255], [-0.939860253923854, 51.60435578228165], [-0.940131370864495, 51.60430877574863], [-0.940224037565311, 51.60429792302206], [-0.941065905352937, 51.604358569226044], [-0.941456261791824, 51.60439985396626], [-0.94172260946072, 51.604433725629356], [-0.942065117075164, 51.604483568721975], [-0.942405972956444, 51.60454238758566], [-0.942542307804962, 51.60457868292929], [-0.942668453620936, 51.60461848302318], [-0.942754322773386, 51.60465162617505], [-0.942930037674105, 51.6047332338937], [-0.94300827141212, 51.60478429141865], [-0.943050642772121, 51.60482513526179], [-0.943095505071305, 51.604883085645305], [-0.943175837511794, 51.60503037259752], [-0.943199044776033, 51.60508812802956], [-0.943264927978451, 51.605360268787045], [-0.94328295289835, 51.6055168856955], [-0.943285556153251, 51.605653582182974], [-0.94327790338372, 51.60573443814757], [-0.943262026480571, 51.60579633763445], [-0.943228365851772, 51.605877858692274], [-0.943092212068021, 51.60614458434088], [-0.943074097962666, 51.60624063192375], [-0.943061365824471, 51.606415854446915], [-0.943044862244347, 51.60650472320056], [-0.943017897594943, 51.606608783583646], [-0.942979591589439, 51.606703750216774], [-0.942905884027612, 51.60683076806164], [-0.942741267849139, 51.60707925374213], [-0.942655006715899, 51.607249318295594], [-0.942630361430127, 51.60731563455148], [-0.942616263944651, 51.607425205688976], [-0.942621958529523, 51.60749089598715], [-0.942636336634899, 51.60755576531453], [-0.942660904708633, 51.607617129739225], [-0.942696981288364, 51.607680396114986], [-0.942747433102709, 51.60774648940761], [-0.942856244975984, 51.6078490746924], [-0.94299552290573, 51.60794563997599], [-0.943040847342192, 51.60798381288104], [-0.943186973159248, 51.608158666884215], [-0.943285889122319, 51.60825217104693], [-0.943509689787491, 51.60844031193307], [-0.94379690141149, 51.609007570967925], [-0.943824004868445, 51.60908424372538], [-0.943831400135399, 51.609201201602104], [-0.943839541642426, 51.60922375393887], [-0.943852077204152, 51.6092436483043], [-0.943874740412961, 51.60926273459518], [-0.943900416430683, 51.60927645299323], [-0.944008015202393, 51.60930709311221], [-0.944074894993692, 51.60934995527111], [-0.944126815315737, 51.60941516198104], [-0.944143328071964, 51.60945037786937], [-0.944150844233183, 51.609499899486615], [-0.944148608042361, 51.60953404761941], [-0.944074023202655, 51.60969882315075], [-0.94403415265091, 51.60986121332522], [-0.944017357658548, 51.60996266784037], [-0.943992023164905, 51.61030771903426], [-0.943965568458423, 51.61051428886229], [-0.943938629028152, 51.61067949277199], [-0.943919488028492, 51.61075754789674], [-0.943885949921455, 51.61083367520212], [-0.943827406881077, 51.61092935920088], [-0.943739589608875, 51.61104186395993], [-0.943638735204063, 51.61115604969767], [-0.943533757272514, 51.611261206608894], [-0.942952360107171, 51.61179457356613], [-0.942768364001955, 51.61194397664764], [-0.942436714102017, 51.61217027698273], [-0.942010518369458, 51.61248743929258], [-0.941742162181165, 51.61266215641604], [-0.941369087685306, 51.61286829880399], [-0.941218061678922, 51.612965845186196], [-0.941055044244821, 51.613082165678385], [-0.940962318642569, 51.61315685920963], [-0.940802313735133, 51.613329853845215], [-0.940532273923746, 51.613638528438315], [-0.940201080800705, 51.61403027273604], [-0.940058816377521, 51.614185443187054], [-0.939985695447699, 51.614286388653916], [-0.939953592073967, 51.614362527773245], [-0.939906859457064, 51.614508669589505], [-0.939802341993177, 51.61490335803689], [-0.939554942446072, 51.615603370947234], [-0.939452722231603, 51.61596121406953], [-0.939421935085161, 51.61604275989804], [-0.939387192811998, 51.616108085051245], [-0.939207265482904, 51.61639149465681], [-0.939036585027605, 51.61671185322904], [-0.938852844916865, 51.61697274874371], [-0.938765881571911, 51.61710953487875], [-0.938636321443754, 51.617400592062225], [-0.93858227703968, 51.617550263869646], [-0.938563060896774, 51.61763101488344], [-0.938557821588965, 51.617793716095726], [-0.938568952285691, 51.6178738422429], [-0.938586194898738, 51.61793963701825], [-0.93864824402059, 51.61806608070808], [-0.938712639101221, 51.61815388154161], [-0.938801458484915, 51.61824729803767], [-0.938902019778203, 51.61833272809444], [-0.939001577491258, 51.61839926656718], [-0.939080060597956, 51.6184404379885], [-0.939144458958051, 51.618466196342986], [-0.93924483456823, 51.61849767462955], [-0.939389936057716, 51.61853135511866], [-0.939533886937889, 51.618552436752374], [-0.939605967169062, 51.618558482633226], [-0.939704125343146, 51.618561167280205], [-0.940011869234288, 51.61855765138392], [-0.940970156479417, 51.61846828865034], [-0.942814559287174, 51.61834913395653], [-0.9433943585448, 51.61832378069166], [-0.943791844341078, 51.61831207069643], [-0.944095316626396, 51.61830580819228], [-0.944345189840605, 51.61830625638639], [-0.944633949874169, 51.618311549349706], [-0.944866264500346, 51.618321729423634], [-0.945069571918896, 51.61833704343469], [-0.945259736594118, 51.618358533188456], [-0.945405071369022, 51.6183823175338], [-0.945538707551366, 51.61841229079249], [-0.945670733169093, 51.618449442740584], [-0.945789657802543, 51.61849097274293], [-0.945898390514756, 51.618536007789324], [-0.946002624502939, 51.61858819565799], [-0.946144975691139, 51.61867849034559], [-0.946290660655923, 51.61881197458077], [-0.946424293873759, 51.618966930407886], [-0.94648587943588, 51.619052004215185], [-0.946597289998464, 51.61923103785771], [-0.946748500992991, 51.619500344620654], [-0.946865282768134, 51.619759451627154], [-0.94692090631825, 51.619852564183816], [-0.946986743272162, 51.619941272483025], [-0.947121992710119, 51.62008904866086], [-0.947221067183078, 51.620177155655796], [-0.947357337089385, 51.62028088174252], [-0.947636341593443, 51.62045871900467], [-0.947732020809812, 51.62050633282523], [-0.947832261440868, 51.62054409665008], [-0.948024909405708, 51.6205835873772], [-0.948272727755043, 51.62061098363029], [-0.94903310890345, 51.62064836261257], [-0.949342820854191, 51.62068530212313], [-0.949548509996597, 51.62072310869445], [-0.949603327033706, 51.620726296510135], [-0.94966121922192, 51.62072141934501], [-0.949725095662238, 51.62070760405018], [-0.949813979767225, 51.620674230793945], [-0.949850856696741, 51.620766275113425], [-0.949938127431095, 51.62092800552347], [-0.95012170684362, 51.62142328688538], [-0.950137689181391, 51.621481875301626], [-0.950144591409982, 51.621558365780544], [-0.950143525838059, 51.62166715485939], [-0.950086848280287, 51.62218276713024], [-0.950081566444785, 51.62234906486587], [-0.950091380322934, 51.6227375905417], [-0.950012857804674, 51.623198158520914], [-0.949963053357781, 51.62366617649237], [-0.94993621019599, 51.62382778558582], [-0.949887611273865, 51.62405573809743], [-0.94981748429385, 51.62434014525264], [-0.949698012983878, 51.6246969431444], [-0.949601071539472, 51.62520410239216], [-0.949519655994856, 51.62547671925938], [-0.949509640700394, 51.62553507516918], [-0.949509569744091, 51.62560071332227], [-0.949517625184728, 51.6256898023632], [-0.949539397678852, 51.62581048474923], [-0.949602831958219, 51.626066413978656], [-0.949622600072634, 51.6262113557699], [-0.949625807500304, 51.62644786389373], [-0.949588359660548, 51.62688092470566], [-0.949587162842075, 51.62718303218221], [-0.949593421398238, 51.627287390862], [-0.949641886384285, 51.62762860642186], [-0.949677564559904, 51.627772791296934], [-0.949732061930258, 51.62791534613564], [-0.949847071945823, 51.62812767746571], [-0.95005020451512, 51.62890367131774], [-0.949860358893705, 51.62924185674224], [-0.949849459019953, 51.62927592739189], [-0.949848649628705, 51.62931098742953], [-0.949857806222275, 51.62935243070728], [-0.949882540677514, 51.62940750068883], [-0.949782851646605, 51.62940750843079], [-0.949684104107472, 51.6296170289926], [-0.949619670293909, 51.62984214210067], [-0.949589348281571, 51.62990391300069], [-0.949478823262764, 51.63006027755304], [-0.949419643728549, 51.63018293320961], [-0.949378577882241, 51.63033452402259], [-0.949364251310331, 51.63051692549393], [-0.949339228920643, 51.63059942443184], [-0.949248633732607, 51.63076855530058], [-0.949181283974238, 51.630869557872636], [-0.949044504574139, 51.63103647701982], [-0.948893935504611, 51.63136242402941], [-0.948761069414249, 51.631297394415576], [-0.948669492362367, 51.63125880992652], [-0.948537801268757, 51.63120547966423], [-0.948447461288637, 51.63117589768262], [-0.948353982967507, 51.63115707745748], [-0.948302104865814, 51.63115121794117], [-0.948079606840815, 51.63115102360314], [-0.947964190602531, 51.63114369566099], [-0.94782149485015, 51.63112892992514], [-0.947725107052886, 51.63111098229264], [-0.947684910040859, 51.63109983219839], [-0.947483021604023, 51.63102069524269], [-0.947447137482345, 51.63101048287877], [-0.947306094892948, 51.630986739722026], [-0.947000710620611, 51.63094713644845], [-0.946674033898238, 51.6308911565172], [-0.946364247153943, 51.63079216747898], [-0.946230490849763, 51.63076579091048], [-0.946172752135344, 51.63076347450912], [-0.94612066649297, 51.630766603772976], [-0.945914796224295, 51.63079712600587], [-0.94583241748209, 51.63079818492752], [-0.945382953779145, 51.63067905708907], [-0.945085984219956, 51.63058827220451], [-0.944883205963743, 51.630547786680644], [-0.944304065189339, 51.630538086402446], [-0.94394898927073, 51.630523204990325], [-0.943611477254356, 51.63049858971805], [-0.943603681926519, 51.6307098224617], [-0.943277115569317, 51.63102249010073], [-0.943359247728321, 51.63109426279834], [-0.942862682241593, 51.631385618132356], [-0.942777562378065, 51.63144239822567], [-0.942532313252267, 51.63161282917167], [-0.942337892928893, 51.63177202827151], [-0.94226606523137, 51.631816339444626], [-0.942197377359527, 51.63184988892168], [-0.942115813951467, 51.631877927416205], [-0.941937005967162, 51.631924871353945], [-0.941512981586086, 51.63201636159427], [-0.94144898217334, 51.6320346671529], [-0.94125937051438, 51.632111184999914], [-0.940790185204025, 51.6323425346351], [-0.940501042462563, 51.632535943664614], [-0.940243238615803, 51.63268647504363], [-0.940131608045529, 51.632764593869275], [-0.939328651391563, 51.63361514453957], [-0.939011405652477, 51.634145481445906], [-0.93882930544315, 51.63451878632893], [-0.93850479164515, 51.63486472819315], [-0.93841585373771, 51.63483694950617], [-0.938308667759282, 51.63503379600045], [-0.938237520065274, 51.63511048065125], [-0.938174497877949, 51.635148574806536], [-0.938097155068085, 51.63518114448376], [-0.938014243480848, 51.63520467214815], [-0.937885103100742, 51.635227781700706], [-0.937899482630853, 51.63529265131639], [-0.937852791962712, 51.635312010611116], [-0.937756752174709, 51.63534081433219], [-0.93768849662133, 51.635355482713884], [-0.937445207164159, 51.63537845841074], [-0.937282775985471, 51.6354039635962], [-0.936848828519967, 51.635485456519916], [-0.935951432459366, 51.63561220386278], [-0.935719677036262, 51.635636179646525], [-0.935420148631615, 51.63565414571281], [-0.935249454884316, 51.63560044703531], [-0.935077590540852, 51.635535048401415], [-0.934717727795324, 51.63535285185533], [-0.934413155884105, 51.635216113905294], [-0.934240481559584, 51.635123731852076], [-0.934130824273522, 51.63505529964683], [-0.934018404467151, 51.63498144729724], [-0.93379675026591, 51.63482118293064], [-0.933679892303923, 51.6347517857655], [-0.933595523374065, 51.63471415412531], [-0.933350473747258, 51.63462740768713], [-0.933261876876166, 51.63458524160035], [-0.933052343088727, 51.63446285066096], [-0.932887751506176, 51.63439571653097], [-0.932638117941304, 51.63431971687678], [-0.932307197466639, 51.63419801967628], [-0.931343887912331, 51.63380981222079], [-0.931071830619705, 51.63376597498289], [-0.930956833347264, 51.63374065092008], [-0.930823331188951, 51.63370346918478], [-0.930701576222194, 51.633658301797674], [-0.930601553796263, 51.63361063468632], [-0.930506119022842, 51.63355221932683], [-0.930386739592999, 51.633467510133144], [-0.930286034494439, 51.633387466714524], [-0.930225334024314, 51.63332666999925], [-0.930188937852857, 51.633276884582266], [-0.930114567680391, 51.63312155131756], [-0.92999324620862, 51.63293521875163], [-0.929900400330813, 51.63282827174111], [-0.929602366751531, 51.6325378240622], [-0.929499431873266, 51.632429885607195], [-0.929341000864788, 51.63222433167361], [-0.929059923028374, 51.631889079042224], [-0.928963213558906, 51.63176231446386], [-0.928896162303318, 51.6316645934755], [-0.928844852932023, 51.631573310156845], [-0.928688841592085, 51.63126527289447], [-0.928672375509884, 51.6312282570475], [-0.928615004479859, 51.631026321392014], [-0.928599834825331, 51.63099561149414], [-0.928552267379979, 51.63092953870757], [-0.928477466267079, 51.630854225808044], [-0.928389580173335, 51.630782390113474], [-0.928294323595921, 51.6307167812279], [-0.928190294396403, 51.63065558801307], [-0.928078937075949, 51.630598823630024], [-0.927494137115659, 51.630339021667446], [-0.927177150281751, 51.63017967221046], [-0.927053070740772, 51.63011110151437], [-0.926922044883713, 51.63003077810591], [-0.926774152423019, 51.6299305188448], [-0.926569924361936, 51.62976860145066], [-0.926465515994788, 51.62966244509719], [-0.926222881099496, 51.62935271335746], [-0.925807083215573, 51.62885077488713], [-0.925685153671251, 51.62869140695483], [-0.925627779063265, 51.628612654944924], [-0.925107975398826, 51.62780494620014], [-0.925039238852947, 51.627717997425265], [-0.924853081975605, 51.627525670804864], [-0.924566287633664, 51.62725149768458], [-0.924018135317732, 51.62666651663998], [-0.9236755124427, 51.62631000590676], [-0.923506463123086, 51.62618886774415], [-0.92325024557972, 51.62602736696645], [-0.923179326155173, 51.62597186775246], [-0.923151247824846, 51.62593744208942], [-0.923025917353845, 51.62573937605691], [-0.922746731858051, 51.625388839233764], [-0.922647729925315, 51.625421200084226], [-0.922438316532782, 51.62517470633975], [-0.922266691774008, 51.62491866820555], [-0.922176577184834, 51.624819832363215], [-0.921722712186069, 51.62440384906751], [-0.921324388846087, 51.624082786314446], [-0.921078577970903, 51.623909687134365], [-0.920860652296657, 51.62377910436709], [-0.920574889783577, 51.623646099345635], [-0.920239048968319, 51.623492851580735], [-0.920014292502202, 51.62371107994427], [-0.919774493442185, 51.623954346092496], [-0.9196346398006, 51.62406455586703], [-0.919395541436808, 51.62427815528515], [-0.919291601043514, 51.624396787581134], [-0.919216417933559, 51.6245210794288], [-0.919153464283899, 51.62467785367513], [-0.919134125069682, 51.624762197061855], [-0.919115026043568, 51.62495803894169], [-0.919049238753011, 51.62517323267518], [-0.919009465019033, 51.625266379578875], [-0.918926652164549, 51.625407685106715], [-0.91889138185638, 51.62549368011671], [-0.918887531877765, 51.62553410703284], [-0.918896749679156, 51.62569334383204], [-0.918892707420934, 51.62574186144837], [-0.918872585162246, 51.62579832350382], [-0.918836276012485, 51.62586722482348], [-0.918763089019947, 51.62596815648993], [-0.918486277330256, 51.626309088016214], [-0.918317614737411, 51.62653682130949], [-0.917905561785174, 51.626975413689514], [-0.917718470441796, 51.62724883363936], [-0.917588198962995, 51.627380709193844], [-0.917518986462533, 51.627435819379606], [-0.917391270738013, 51.627520961779815], [-0.916852199941663, 51.62783249660931], [-0.916708494011591, 51.62822500463541], [-0.916564194300437, 51.62882431452802], [-0.91642514281193, 51.62950639562586], [-0.916399138398425, 51.62974892972319], [-0.916394191477189, 51.62995659074321], [-0.917260413231125, 51.62992321851857], [-0.917422640699178, 51.63166639247214], [-0.91745600722272, 51.63232848375385], [-0.917204699151121, 51.632324368705305], [-0.916787813832452, 51.632356490901394], [-0.916473041038736, 51.63240843616508], [-0.91615824611563, 51.63246127954521], [-0.916096846672852, 51.632491284427324], [-0.916000979824314, 51.632573122584574], [-0.916035541448316, 51.63300234215989], [-0.916058746179642, 51.633180590521675], [-0.916070697537387, 51.63322475979131], [-0.916098260729099, 51.63328076225654], [-0.916287121367376, 51.6334803208717], [-0.916556537933578, 51.63369500893812], [-0.916833436931067, 51.63389897542989], [-0.916980624704717, 51.63396776999687], [-0.917236275570907, 51.634093312450645], [-0.91746761535009, 51.63414759643489], [-0.917599467742121, 51.63382870989293], [-0.917652284973834, 51.63367364156546], [-0.917677934007693, 51.63362802065708], [-0.917745133700401, 51.63359716923921], [-0.917749446066394, 51.633598108140106], [-0.917778102484095, 51.633608262991594], [-0.918084580428658, 51.633662338963], [-0.918258883815884, 51.633684625273325], [-0.918506861448772, 51.63370758977881], [-0.918953829589691, 51.63374767133924], [-0.919245145699076, 51.633771033193085], [-0.919300707852053, 51.63386505735126], [-0.919518444759651, 51.63449197843591], [-0.919277685382965, 51.63446908250848], [-0.919031520477806, 51.63467362436313], [-0.918786199566619, 51.63490335001199], [-0.918632752044247, 51.63503681158531], [-0.918623327237537, 51.63512933850577], [-0.918590569006466, 51.635413172104], [-0.918679820058316, 51.63554886817429], [-0.918329488250497, 51.63557621368664], [-0.918276435808259, 51.635741170885815], [-0.918247752304029, 51.6360358318421], [-0.918226764712395, 51.6364321689642], [-0.918316733144818, 51.63702374696847], [-0.918287332378286, 51.63783452012518], [-0.918306713699577, 51.63835621240955], [-0.918316674296085, 51.639213205140855], [-0.918347519668651, 51.639799742499974], [-0.918322169732004, 51.63995416480466], [-0.918318885834364, 51.64003146244247], [-0.91832686087795, 51.64012145202931], [-0.91837911416845, 51.640354816042915], [-0.918418495846573, 51.64070405330022], [-0.918530296534871, 51.64128953760163], [-0.918512952473936, 51.64147190762244], [-0.918367217757134, 51.64200916315153], [-0.917905817511154, 51.6420255938785], [-0.917874522823857, 51.64200462484983], [-0.9178264462409, 51.64196012300076], [-0.917792775459127, 51.641917552189355], [-0.917773553228143, 51.64187511449974], [-0.917765526057023, 51.64184806570082], [-0.917757894232724, 51.6417436926823], [-0.917749532884981, 51.64142711089125], [-0.917739557627689, 51.64136048104305], [-0.917720785029217, 51.641299165096676], [-0.917688816437575, 51.64124581999865], [-0.917649452591449, 51.641199600032465], [-0.917568381483579, 51.64114490323613], [-0.917433423830488, 51.64098630616572], [-0.917315173490429, 51.64079369481265], [-0.916601390868836, 51.640243120219885], [-0.916329281834837, 51.640018517003504], [-0.916001068304932, 51.63966211774633], [-0.915790319174844, 51.63947044935813], [-0.915502073944432, 51.63913509831614], [-0.915393357554307, 51.63902799332443], [-0.915169439572157, 51.63884339546647], [-0.914312592230519, 51.638234837864296], [-0.913969150495335, 51.63797270396478], [-0.913808719070197, 51.63773204326735], [-0.913709021859032, 51.63761063348384], [-0.913238840648949, 51.637814889395024], [-0.912211197236081, 51.63818662075986], [-0.912057780107923, 51.6382571327065], [-0.911911629192503, 51.63832591344631], [-0.911683066608314, 51.6384568717294], [-0.911571655864317, 51.638583520328496], [-0.910821072629623, 51.63897039510019], [-0.910799442348496, 51.63890815232427], [-0.910457034748542, 51.63884473254883], [-0.90959863753988, 51.63872527019996], [-0.909397970101408, 51.639078576087414], [-0.909048252097236, 51.63925965643008], [-0.909362542404515, 51.63959166868019], [-0.90780907162756, 51.64013291512084], [-0.906217399025103, 51.640939038154336], [-0.905898125060113, 51.64111499768922], [-0.905490384709512, 51.641363863281036], [-0.905329841704473, 51.64154939281248], [-0.905189541321435, 51.641794455508446], [-0.90489098319803, 51.64194992468491], [-0.904781623731163, 51.641990266433346], [-0.904676706895303, 51.64202615370086], [-0.904609919053975, 51.64203901826923], [-0.904237228330216, 51.64209218907456], [-0.90337364044862, 51.64224597828853], [-0.902975191138407, 51.642348358507896], [-0.90292303291413, 51.6422939216028], [-0.902563354675933, 51.64240655335107], [-0.902346768622897, 51.642458479170756], [-0.900824166346957, 51.64291090498388], [-0.900831401206159, 51.64297031739377], [-0.900456613238591, 51.64299018760407], [-0.900019098619797, 51.64297440185565], [-0.899740380937974, 51.64290615240652], [-0.899740489711103, 51.64290165761423], [-0.899316872364163, 51.642849133775655], [-0.899203336991784, 51.642822893203494], [-0.898949902655656, 51.64272520647125], [-0.898783095909619, 51.642631028913314], [-0.898613530793898, 51.64253143027416], [-0.898274969154989, 51.64230885935864], [-0.898003026265053, 51.642080618381755], [-0.897815191816853, 51.641840577798526], [-0.897681652652772, 51.6416262230417], [-0.897327401428262, 51.64091885338664], [-0.896908641882592, 51.6401308512027], [-0.896689777704333, 51.63985994571793], [-0.896199107519928, 51.639356299928586], [-0.896147069948886, 51.63929736526477], [-0.896071667668875, 51.63912941223961], [-0.896034388155249, 51.63881974973283], [-0.89604243255033, 51.63866696761571], [-0.896079873457203, 51.63849378104931], [-0.896158355572289, 51.63829670279626], [-0.896345617779906, 51.63796397393339], [-0.896436991088377, 51.637771512438086], [-0.896627579786388, 51.63748017587825], [-0.896853716275347, 51.63721255114492], [-0.896930541034958, 51.63714313797598], [-0.897052325259386, 51.63706695367484], [-0.897622203318074, 51.636806151704704], [-0.897875248140837, 51.636679946210485], [-0.898045509693898, 51.63657094674504], [-0.898161794997489, 51.63648302058021], [-0.898300490282884, 51.636364732965696], [-0.898761753797595, 51.63587451909389], [-0.898944791614438, 51.635595696246455], [-0.899167964890093, 51.63497197055003], [-0.899296205851425, 51.63450920414348], [-0.899574174378538, 51.633591065468096], [-0.89965934952667, 51.63323579470252], [-0.899745200652967, 51.632733067337156], [-0.89977291429982, 51.632065248259224], [-0.899749317297925, 51.63190587518938], [-0.899730833669311, 51.631833768913715], [-0.899698165870897, 51.631750739777836], [-0.89965967663145, 51.63166945441679], [-0.899415121605884, 51.63126703489972], [-0.899342021743563, 51.6311233827535], [-0.899274678557411, 51.630980683675816], [-0.899221406706553, 51.63067446858268], [-0.899099405183406, 51.63046202142283], [-0.899036514315775, 51.63037421293725], [-0.898969246754073, 51.63028816171176], [-0.898790586842518, 51.63008867047265], [-0.898592010806669, 51.62987640386868], [-0.898497321924236, 51.62978919602221], [-0.898330098469121, 51.62965455114822], [-0.898092642525963, 51.62949676796704], [-0.897090362270362, 51.62894426419184], [-0.896737033461809, 51.62879887742956], [-0.896347312922056, 51.6286648367393], [-0.895633444660858, 51.62837398981453], [-0.895432402381131, 51.628264199314984], [-0.895328663542796, 51.62819308870188], [-0.895257753282041, 51.62813847178444], [-0.895144755729953, 51.62803220648194], [-0.894948239644532, 51.627795675481295], [-0.894944118635818, 51.62766795529761], [-0.894659948504904, 51.62723368184], [-0.894597856997988, 51.62711350846984], [-0.894557343909314, 51.62699713484451], [-0.894469809950127, 51.62655661915932], [-0.894297931114171, 51.625960652861906], [-0.894027819576293, 51.62530531541029], [-0.893931965007508, 51.62514795788166], [-0.893770350871199, 51.62496210671055], [-0.893637995566781, 51.62476124514902], [-0.893507481839104, 51.62466290563429], [-0.892108104715385, 51.62369479825078], [-0.891788795844237, 51.623459800649094], [-0.891922368328922, 51.62337294285213], [-0.891402229815371, 51.62296161084893], [-0.891224922435199, 51.622768414566416], [-0.890089770742591, 51.621276764770215], [-0.890188416566163, 51.62120036880181], [-0.889947380146256, 51.62101466068101], [-0.889727152716072, 51.62086421627997], [-0.889328903798693, 51.62066892786315], [-0.889153387824523, 51.620758083474584], [-0.888409981594066, 51.6201459098237], [-0.888016456293258, 51.619876030785385], [-0.887588982852847, 51.619754191291285], [-0.887143566599165, 51.61965735685454], [-0.88701981132148, 51.61963820065132], [-0.886790744842007, 51.619613550199404], [-0.886603228328527, 51.619602780759124], [-0.886388075513318, 51.619599841439666], [-0.886090409498186, 51.61960421155123], [-0.8851368584814, 51.61967159165818], [-0.883828125903616, 51.61979133688442], [-0.883515973065361, 51.619797361107345], [-0.883424375160774, 51.6198216668555], [-0.883259776293847, 51.619877648328995], [-0.883163867754863, 51.61990101371408], [-0.883044634749604, 51.619815357981636], [-0.881854770311083, 51.61956485587701], [-0.881704286246311, 51.61951666620604], [-0.881635675440863, 51.619487239450166], [-0.881560131370525, 51.619446057447796], [-0.881477720403852, 51.619390423316226], [-0.881374708667671, 51.619291432867335], [-0.880834298239682, 51.61853547912722], [-0.880617549323506, 51.618127888748454], [-0.880388345702594, 51.61816796449318], [-0.879226788544387, 51.6185884841998], [-0.878534686661489, 51.61883184500677], [-0.878385021629543, 51.61898507235025], [-0.878148819949825, 51.61913297697072], [-0.878102165244257, 51.61915051459153], [-0.87804120240859, 51.61916252048532], [-0.877967464227806, 51.619165412606506], [-0.877896924603018, 51.61915574690363], [-0.877839648002824, 51.61913541789456], [-0.877812586845032, 51.61911987344738], [-0.877382402665225, 51.61869944717381], [-0.877261875140598, 51.61866682400238], [-0.877087293116294, 51.618600414623565], [-0.876592344555959, 51.61846350297477], [-0.876408990128558, 51.61845995037962], [-0.876374465270622, 51.61845422502283], [-0.876347205240439, 51.61844677083749], [-0.87630299358364, 51.61842386858449], [-0.876241963569583, 51.618380124514495], [-0.876216636094276, 51.618352907107045], [-0.876152781748704, 51.618131100785114], [-0.876106882196741, 51.61811807314475], [-0.876305643178539, 51.617614643124426], [-0.875030363348109, 51.6174927341714], [-0.874705473526163, 51.61748872204597], [-0.874564111923802, 51.6174810731233], [-0.874279482039409, 51.61730930128958], [-0.874259717266618, 51.61699889890464], [-0.874416434195306, 51.61673604585861], [-0.874423036602998, 51.61652750219062], [-0.870144618410033, 51.61769939147719], [-0.870074692270606, 51.617607003497994], [-0.869665459226217, 51.61768399010514], [-0.869137937974611, 51.617812887107476], [-0.868711126950696, 51.61789959196275], [-0.868460959800069, 51.617969115035805], [-0.866874516019656, 51.61827841686334], [-0.866642434191741, 51.6183175388698], [-0.866517885416195, 51.61833072340073], [-0.866392071649004, 51.61833670224208], [-0.865776872894858, 51.61833166083683], [-0.865633662902087, 51.618340168339564], [-0.865493072065054, 51.618359490991885], [-0.864874419821269, 51.618492883413026], [-0.864829070270363, 51.61851582340227], [-0.8648101986804, 51.61846169086974], [-0.864778464993556, 51.618402038980314], [-0.864733824417545, 51.61833866562683], [-0.864681918741689, 51.61827702035103], [-0.864649512487616, 51.61824433697217], [-0.864492159027339, 51.61812502442397], [-0.864510219622979, 51.618037979732996], [-0.864490008258273, 51.61792179156664], [-0.863791866117017, 51.616668790850674], [-0.863578496430752, 51.61619016667409], [-0.863939572338851, 51.6160749702936], [-0.864141702322916, 51.61602027805823], [-0.864343742093738, 51.615969181278444], [-0.864684853799959, 51.61590144547291], [-0.864287415633653, 51.61573755014447], [-0.864114344880943, 51.615611790807684], [-0.86394143216696, 51.615479738556914], [-0.863424226660599, 51.6150224515856], [-0.863108525016747, 51.61470918210108], [-0.862999136822108, 51.61463618943345], [-0.862947760773663, 51.614611414387845], [-0.862827479233939, 51.614569786988696], [-0.862764327092327, 51.6145538895073], [-0.862690954996651, 51.614542388851355], [-0.862422671693898, 51.614528100870835], [-0.862278208948609, 51.61452939875511], [-0.862025067586916, 51.614544929155834], [-0.861633333855888, 51.61461576315295], [-0.861195617216796, 51.61467715820802], [-0.860991546767721, 51.61469406144679], [-0.860819513274215, 51.61470048511226], [-0.860591345418716, 51.61469917048917], [-0.860366335624517, 51.61468709604235], [-0.860199196800327, 51.61467108707321], [-0.860140174693704, 51.6146633207896], [-0.859842784619867, 51.61460018922178], [-0.85969929013584, 51.61456282905675], [-0.859501466379857, 51.61450336097874], [-0.859306643699259, 51.614439425872085], [-0.859175017225196, 51.614389591981386], [-0.858977780895874, 51.61430675031806], [-0.858172868778381, 51.61392127488393], [-0.856305510909038, 51.61299763777437], [-0.855879431428414, 51.61282624136621], [-0.855413827571698, 51.612676038205095], [-0.855073660630441, 51.61259179657028], [-0.854915624510577, 51.612558784566126], [-0.854688372582268, 51.61252150056368], [-0.854459541396129, 51.6124895957323], [-0.854208848612115, 51.61246556965946], [-0.853413812340721, 51.612436228916096], [-0.851724243907319, 51.61242871018406], [-0.851450292115, 51.612410744947404], [-0.850998615679464, 51.61233888823236], [-0.850653274334699, 51.61223120468302], [-0.850372939737194, 51.61235164666859], [-0.850315593337778, 51.61233490012849], [-0.850193999216673, 51.612288751000705], [-0.850146601119627, 51.612278395984944], [-0.849926028861458, 51.61226274823948], [-0.849854084982468, 51.61225215268858], [-0.849714847013531, 51.612218418620564], [-0.849473435162227, 51.61217019573735], [-0.849372523204365, 51.61216291272777], [-0.849235958321253, 51.61219484371945], [-0.849170915863905, 51.6121969037703], [-0.849112126238191, 51.61218014249445], [-0.8487984760956, 51.61201881385575], [-0.848813983178796, 51.61186251023449], [-0.848805967905994, 51.611779707971536], [-0.848777693193183, 51.61169850541887], [-0.848751669639592, 51.61164250170296], [-0.848740414389996, 51.61163070213332], [-0.848685616135578, 51.61162746733029], [-0.848598109857592, 51.61148993537107], [-0.848561752293423, 51.61144282198033], [-0.848420551583887, 51.61131555337684], [-0.848346143135118, 51.61123120073643], [-0.848017978126262, 51.61073074025961], [-0.84803240586268, 51.61067423405594], [-0.848009203184881, 51.61062095534751], [-0.848010806265629, 51.61061467688053], [-0.848360723390725, 51.61054078070849], [-0.848731046077576, 51.61040234328455], [-0.848814480324059, 51.61035820278237], [-0.848820437461021, 51.610351067821576], [-0.848690278305866, 51.610072847084595], [-0.847947554822518, 51.60900543974003], [-0.847435103308081, 51.6083125448088], [-0.847167998407497, 51.60796823756615], [-0.846186886755928, 51.60662333116728], [-0.845549998419521, 51.605828497430636], [-0.845383680959569, 51.60566770865375], [-0.844840468159951, 51.60522267062485], [-0.84443530295085, 51.60497141150611], [-0.844232696249957, 51.60481835643492], [-0.843486943931864, 51.60416181103064], [-0.84332558359401, 51.60420428093958], [-0.842908147301968, 51.603868373383044], [-0.842663709069561, 51.603714004109015], [-0.842310199280505, 51.603533382087996], [-0.841471682375652, 51.60311958453644], [-0.841215384127901, 51.602977683579475], [-0.840873068217364, 51.60281155440105], [-0.840467421086961, 51.602637605395635], [-0.840268344470896, 51.602516948405764], [-0.840203154295604, 51.60246864832527], [-0.838474883614574, 51.601841924417336], [-0.838334815858368, 51.60178568911777], [-0.838125139250388, 51.60168470536249], [-0.837520083534699, 51.60134782062488], [-0.837365310402971, 51.60124558073874], [-0.837143016970701, 51.6010734356079], [-0.83702163004049, 51.600964332538595], [-0.836879440722268, 51.60082175386177], [-0.836733036616179, 51.60067463738169], [-0.836105420124444, 51.59992210370809], [-0.836001567218505, 51.59980508080317], [-0.835894758960057, 51.59969072601903], [-0.835646409012494, 51.5994652683849], [-0.835572705263831, 51.59941148620318], [-0.835355212679077, 51.599278049641256], [-0.835001490423373, 51.59910819321327], [-0.834666328550124, 51.59894661249016], [-0.834023851532118, 51.59860753956394], [-0.833813699592692, 51.59846967713012], [-0.832219972267628, 51.59727861587006], [-0.831975375091702, 51.59713321406168], [-0.83180286996819, 51.597047874561696], [-0.83156138306724, 51.59695015903964], [-0.831279067386554, 51.596868221715724], [-0.831119729288761, 51.59683246683902], [-0.830996129682144, 51.596810555210986], [-0.830798964246538, 51.59678611250204], [-0.829935838169309, 51.596720865686486], [-0.82967342169104, 51.596707460026586], [-0.829378950815281, 51.59670542343618], [-0.828672101908656, 51.596738836236966], [-0.828529092462618, 51.59674190522934], [-0.828241907711544, 51.596737240965595], [-0.828066024571149, 51.59672739285258], [-0.827854311754233, 51.596707295846045], [-0.827399248313258, 51.59666228882735], [-0.827164974703315, 51.59662128423301], [-0.827063074447412, 51.59659778687348], [-0.826830893268571, 51.59653162563389], [-0.826403126611598, 51.596379885757386], [-0.826320361645679, 51.596342192238744], [-0.826196596762853, 51.596270819297594], [-0.825930135887572, 51.596078429107884], [-0.825702044863314, 51.59590980062742], [-0.825239717878873, 51.595531118786504], [-0.824901250965003, 51.59522021379687], [-0.824412039116432, 51.59470908081712], [-0.8242790371805, 51.59460434384618], [-0.824162427084317, 51.59453573788591], [-0.823734544991122, 51.59433363318264], [-0.822923577534385, 51.59387232098135], [-0.82274220720895, 51.593740122024236], [-0.822758790294358, 51.59343366962803], [-0.822450529949737, 51.592123177421634], [-0.822408018987733, 51.591980681321466], [-0.82236394886053, 51.59184266543808], [-0.822242174035691, 51.59158338051977], [-0.821801765862476, 51.5908065697487], [-0.821372709449585, 51.59009371260957], [-0.821171850754746, 51.58982284235581], [-0.820679968304875, 51.58936291919855], [-0.820417155492676, 51.58914357740762], [-0.82015811620844, 51.5888901042506], [-0.820045903377484, 51.58876399099103], [-0.81975498206002, 51.5884040936899], [-0.819793038416411, 51.58838379523831], [-0.819648800144719, 51.588268149727725], [-0.819147039514258, 51.58763368041164], [-0.818936357700162, 51.58740856531028], [-0.818746726401906, 51.58698404449756], [-0.818744261992127, 51.58691208559554], [-0.818786542624285, 51.586561832259704], [-0.818798419467402, 51.58638211648965], [-0.818772601288344, 51.58593047014409], [-0.818622316220491, 51.585380460186784], [-0.818493730937228, 51.58471737211902], [-0.818460174123387, 51.58461992329734], [-0.818316632401033, 51.58436670899539], [-0.818092592164715, 51.58404524580265], [-0.817774082795079, 51.58341531231479], [-0.817553796530972, 51.58311636524129], [-0.817445537064436, 51.58300557512581], [-0.81689125274485, 51.582562990062094], [-0.816348587477007, 51.58217357091916], [-0.816214612729635, 51.58210837837547], [-0.816144330954904, 51.58209148442308], [-0.816059129697027, 51.58209332267878], [-0.815742672724781, 51.5820523651453], [-0.815217212787465, 51.58194545592985], [-0.815002344756643, 51.58188304223224], [-0.814826435408141, 51.5818210214772], [-0.814485295861823, 51.581730356582035], [-0.81444044205173, 51.581790148477246], [-0.813566956536122, 51.581635656767844], [-0.813282023122958, 51.58154825394594], [-0.813052037332166, 51.581456910143594], [-0.812870182657061, 51.581346270732034], [-0.812790810356639, 51.58129061819263], [-0.812604263086127, 51.581138568732094], [-0.812386509085548, 51.58085492331321], [-0.812249092317067, 51.58070067277682], [-0.812167619564544, 51.58055957666617], [-0.812051961231651, 51.58029045130041], [-0.812042798783181, 51.580254391465495], [-0.812034433182585, 51.580187767648724], [-0.812033188044369, 51.58012481260171], [-0.812058064730261, 51.580000977815104], [-0.81229781440549, 51.579440518478464], [-0.812247901650195, 51.57941753400863], [-0.812446355706805, 51.57916777205078], [-0.81277233113049, 51.578787120404634], [-0.813191367818544, 51.57821318632392], [-0.813476583358647, 51.57767926033569], [-0.81372993476285, 51.57714950751218], [-0.813894821439398, 51.57669169369027], [-0.813998634879093, 51.57614064720803], [-0.814138744624452, 51.57508193151095], [-0.814120940539715, 51.57493428638376], [-0.81419874804071, 51.57321943977239], [-0.814492542549023, 51.572575897898666], [-0.814547744449169, 51.57211787423915], [-0.814549364628156, 51.57200009817749], [-0.81449843948966, 51.57157247390041], [-0.81447275908744, 51.57022974030085], [-0.814470739157426, 51.56964165674743], [-0.814429823166273, 51.56938407823071], [-0.814416473674158, 51.5693425811485], [-0.814362577800679, 51.569251219648685], [-0.81406844007837, 51.5689659058573], [-0.813908308238922, 51.56874308971205], [-0.813853532979604, 51.56863013877188], [-0.81375715260415, 51.56839717647337], [-0.81371284208748, 51.56815934527622], [-0.813667666933597, 51.567788426746645], [-0.813915408556528, 51.567527470860746], [-0.814280993234198, 51.56684059466537], [-0.814704823511867, 51.56613272518902], [-0.814994772052415, 51.56569055892733], [-0.815202529336662, 51.56519091397622], [-0.815219131565213, 51.56505170869626], [-0.815351636137841, 51.564671793906264], [-0.815511116853932, 51.56436408558186], [-0.815565592175225, 51.5642108755608], [-0.815662011458114, 51.564053592855515], [-0.815731002538058, 51.56389693250399], [-0.815762954470268, 51.56377766396064], [-0.815882314039101, 51.56307031436626], [-0.815899206541573, 51.563030920866616], [-0.815918960262566, 51.5629924554096], [-0.816100387305838, 51.56272812828101], [-0.816239061970809, 51.562387838558415], [-0.816351227865814, 51.56217946080997], [-0.816402225233145, 51.562104443964415], [-0.816445731089239, 51.56204014171416], [-0.816755073070336, 51.56173843863565], [-0.81682883069147, 51.5615089920632], [-0.81709149295673, 51.56100450196165], [-0.817126546068515, 51.5610435199925], [-0.817036868291134, 51.56144185218239], [-0.817602599672938, 51.56148891511105], [-0.817650902097453, 51.56129517879352], [-0.81772376875861, 51.56109989153342], [-0.818544773098936, 51.56114952106405], [-0.818940645385275, 51.56112652991029], [-0.819286252234888, 51.56087194248433], [-0.820505192935939, 51.560762809232635], [-0.821152924392013, 51.56109751750433], [-0.821401734784996, 51.56112699167495], [-0.821468077854438, 51.561127657861135], [-0.821837057068471, 51.56108460493917], [-0.822551882107614, 51.56083281445182], [-0.822991148836609, 51.56069335159132], [-0.823298868990794, 51.56056425765945], [-0.823427756279142, 51.560489119484224], [-0.823816316952276, 51.56018999039105], [-0.823841530161624, 51.56016326766115], [-0.823879440321637, 51.5600917131651], [-0.823939663402364, 51.55926686943448], [-0.824000930577316, 51.55924050793579], [-0.823876052668265, 51.55798579953388], [-0.823797968341331, 51.557154174451156], [-0.823813910366727, 51.55698348995032], [-0.824268965579194, 51.556733581409404], [-0.824612742777356, 51.55649154853787], [-0.826344281900068, 51.55484359477631], [-0.826657025878971, 51.55457337099326], [-0.827233265990788, 51.554040521447654], [-0.827929376968602, 51.55344502444081], [-0.828029419518581, 51.553368693973354], [-0.828246668974642, 51.55322159923911], [-0.828485269800709, 51.5530855074047], [-0.828605105979095, 51.55302466009866], [-0.829372820563392, 51.55267264797847], [-0.830416538296143, 51.552300003050114], [-0.830341853307235, 51.55217517181714], [-0.830015969895102, 51.55217192349864], [-0.82991663595149, 51.55216463892005], [-0.829524156953837, 51.55211486704629], [-0.829282415323888, 51.552092673855796], [-0.828838545910614, 51.55207835426137], [-0.828599504055965, 51.55206338004898], [-0.828680519991051, 51.55199764928292], [-0.828534433277995, 51.55195752639793], [-0.828384829125967, 51.55188589688778], [-0.827987906418731, 51.55167242458396], [-0.827957477145366, 51.551621766572], [-0.827834232346298, 51.55159086272802], [-0.827633977763617, 51.551525919798664], [-0.827259642164726, 51.55144395104261], [-0.826879262755715, 51.5513727108443], [-0.826619197529414, 51.551334143723224], [-0.825020961294276, 51.55117248609027], [-0.825087548806697, 51.55099511486544], [-0.825080332863119, 51.55093929339289], [-0.825041927300218, 51.55086247849746], [-0.82502361605882, 51.55078946149474], [-0.825044884876699, 51.55069166368164], [-0.825058487270179, 51.550667521970404], [-0.82509857658956, 51.550622964257876], [-0.825145597538488, 51.55058926609727], [-0.825325151596322, 51.5505056412203], [-0.824909915146001, 51.550164291306395], [-0.82525013660448, 51.550002248032946], [-0.825332063085088, 51.549957209837], [-0.825638185418255, 51.54977504214384], [-0.82578350044032, 51.54967668704559], [-0.825923116734683, 51.54957557721289], [-0.826170603160388, 51.54937393870707], [-0.826371785812396, 51.54917813090106], [-0.826492161334072, 51.549039961540565], [-0.826611394860751, 51.548890091280356], [-0.82670116630089, 51.54876420424681], [-0.826782355507479, 51.54863553380353], [-0.826823019292071, 51.54856850170786], [-0.827062757600335, 51.548106920435835], [-0.827101368877001, 51.54800749719491], [-0.827194201898492, 51.54770629998806], [-0.827307057244965, 51.54741159704493], [-0.827582602426052, 51.54684696658141], [-0.827901482950928, 51.54639156924703], [-0.828226190833503, 51.54604592938406], [-0.828636291311094, 51.545744301711125], [-0.82879259021163, 51.54566673370386], [-0.828904643767125, 51.545627388779295], [-0.829074413403866, 51.54558682127211], [-0.829642313890905, 51.54554213206049], [-0.831137752395514, 51.5457125947128], [-0.831296230672639, 51.545718668970665], [-0.831381409559054, 51.545715021306385], [-0.831520416985355, 51.54569302674314], [-0.831658465956176, 51.54565213966273], [-0.832162223002951, 51.54540897973132], [-0.832259763552867, 51.545373083913695], [-0.832342495362879, 51.54535232675641], [-0.832449690786029, 51.545333611293344], [-0.832560958333776, 51.54532482723805], [-0.832748224427793, 51.54533298427906], [-0.833594396864807, 51.5455158387706], [-0.833803468208608, 51.5455736658201], [-0.834066591719905, 51.54566080332341], [-0.834319302360527, 51.54576042533909], [-0.834632701147966, 51.545911902800114], [-0.834743597643834, 51.54597414830218], [-0.834972095381443, 51.546118487532766], [-0.835101437527799, 51.546192605160904], [-0.835308853525451, 51.54642845092972], [-0.835597379030446, 51.546650714213946], [-0.835675530378703, 51.54669644865621], [-0.835765285050956, 51.54673960061442], [-0.835946924814448, 51.54679895002405], [-0.836738145066418, 51.54693268079673], [-0.837616543696299, 51.54698454508781], [-0.837668585980954, 51.546979665457], [-0.837867989708348, 51.546964555807335], [-0.83797367625272, 51.54694851789646], [-0.838105566972017, 51.54692284834119], [-0.838233315283634, 51.54688994418392], [-0.838329229403341, 51.54686122067977], [-0.838482151664417, 51.546802489195365], [-0.839036827411148, 51.54642762424692], [-0.83955396219585, 51.54605418383688], [-0.840116011657223, 51.54567219327131], [-0.840736658187885, 51.54525391246058], [-0.840941426195899, 51.54514083988849], [-0.841049279937165, 51.54509604683764], [-0.841194847094701, 51.5450426342828], [-0.841299520083949, 51.545009498946165], [-0.841898633062652, 51.544870644649805], [-0.842282244574123, 51.54481328536381], [-0.842762474116396, 51.54475597844143], [-0.843565178344648, 51.54477737891959], [-0.844086979548171, 51.54484366398717], [-0.845732620874625, 51.545006428046236], [-0.847066038668597, 51.54519847249473], [-0.847735465249349, 51.545415455459946], [-0.84773690700669, 51.54541546961599], [-0.848634731053663, 51.54572550693968], [-0.849946581441456, 51.54620234699594], [-0.850255922443757, 51.54628810259981], [-0.850450510421732, 51.5463493547082], [-0.850677807173489, 51.54642891042725], [-0.850994850981171, 51.546552505063595], [-0.852786328510159, 51.547342426670774], [-0.85300310746802, 51.547496506935786], [-0.853571212311598, 51.54778799706584], [-0.854020445083318, 51.54798930492918], [-0.854581807452525, 51.548205193183556], [-0.85478620907829, 51.54827822314386], [-0.854963577157503, 51.54833660211785], [-0.855161244465997, 51.54839068294659], [-0.855663052553423, 51.5485088736389], [-0.856166529832507, 51.54867563412252], [-0.856279761006, 51.54870371304979], [-0.856530960852844, 51.54875111981111], [-0.856804082121709, 51.54878705024175], [-0.857112033920981, 51.54881432744164], [-0.857381573472553, 51.548820548731904], [-0.857549123049589, 51.54881049056259], [-0.857844479857821, 51.548764809719025], [-0.858057604662229, 51.54872012637499], [-0.858337617310588, 51.54865361386837], [-0.858552497890933, 51.54859635820055], [-0.859049392399301, 51.548450127924276], [-0.859439117962245, 51.5483792842905], [-0.859697682244768, 51.54836291412634], [-0.859779823131423, 51.54836551056866], [-0.860170027263243, 51.548390881318824], [-0.860456238387038, 51.54842243448379], [-0.861009536104037, 51.548500639150554], [-0.861158816462501, 51.54852906321894], [-0.861352413335375, 51.54857320311727], [-0.861544411683264, 51.54862362144007], [-0.861731905414109, 51.5486811891874], [-0.862073439754406, 51.548807688741114], [-0.86254414698236, 51.54901726458452], [-0.86282747298222, 51.54916477803516], [-0.863015068128655, 51.549276295417606], [-0.863120154717426, 51.549342054318615], [-0.863285809311142, 51.54946594721784], [-0.863418211576468, 51.54959311456195], [-0.863530092020445, 51.54973357070672], [-0.863653360363745, 51.549937978681236], [-0.863733641061499, 51.550131180181424], [-0.863790336700716, 51.5503448343906], [-0.863824973966162, 51.550691353426465], [-0.863841717303786, 51.55100353042492], [-0.863889686614544, 51.55116225019172], [-0.863971345177536, 51.55135816235228], [-0.864192531443895, 51.5518009005184], [-0.864636908176204, 51.552606367995786], [-0.864885616784935, 51.55304487507487], [-0.864984710926909, 51.55317801261536], [-0.865042267578469, 51.5532415116859], [-0.86524661818949, 51.553434113390985], [-0.866448255146234, 51.55464702695421], [-0.866553639357719, 51.55475954277147], [-0.86713929523259, 51.555454866418074], [-0.86728119491555, 51.55560729781788], [-0.867357192432134, 51.55568356216347], [-0.867846797612144, 51.55612348793147], [-0.867948777192819, 51.5561991033314], [-0.868039688780355, 51.55625572917072], [-0.868162193200772, 51.55631805467487], [-0.868334859667638, 51.55639345221028], [-0.868507816648064, 51.556457162985154], [-0.868686743286876, 51.556512838449954], [-0.868885971532242, 51.55656421341042], [-0.869870431325262, 51.55700170522159], [-0.870538382015661, 51.557289577406756], [-0.87065953954758, 51.55734829060127], [-0.870968323528286, 51.55751940747054], [-0.871084688448939, 51.55759695683154], [-0.871173919806704, 51.55766345498963], [-0.871421843971099, 51.55790412108149], [-0.871517352960249, 51.558008444760674], [-0.871560414081151, 51.55807539786269], [-0.871689483441928, 51.558339198343305], [-0.871715457861831, 51.558455441841], [-0.871819115572425, 51.558871857901316], [-0.872116688986198, 51.559438501590606], [-0.87224925001588, 51.559678057158926], [-0.872395481580982, 51.5598898694294], [-0.872503199025109, 51.56002578071336], [-0.872616797176149, 51.56015725249727], [-0.872767427555836, 51.560307962534345], [-0.873712440787397, 51.560887112412736], [-0.874019840047307, 51.56105730856152], [-0.874413245272104, 51.56124990894107], [-0.875159636577155, 51.56157807024888], [-0.875469862748955, 51.561692540724444], [-0.875618818634067, 51.561736229028845], [-0.87605776549836, 51.56183754414599], [-0.876366373823489, 51.56190074371407], [-0.87668521195865, 51.561958645316366], [-0.876968369886447, 51.56200091867397], [-0.877197163756339, 51.56202468778881], [-0.877516822654725, 51.5620493254706], [-0.878098847659676, 51.56208186543848], [-0.879220205739232, 51.56212315048378], [-0.879742407250114, 51.562124539056946], [-0.8803196812009, 51.56211566057546], [-0.88047709073344, 51.562109069498774], [-0.880781923890852, 51.5620912956137], [-0.881058065229737, 51.56206695318683], [-0.881262135404653, 51.56204012483733], [-0.881418631531618, 51.562011943580096], [-0.881649213834679, 51.56196288783239], [-0.882003250428868, 51.56187993977645], [-0.882376388095226, 51.56178278572967], [-0.882764299497775, 51.56167138432022], [-0.883194585739291, 51.561537905452155], [-0.883498576630078, 51.5614364931922], [-0.883756281221724, 51.56134003501421], [-0.884086956514705, 51.56120920221847], [-0.884407665982054, 51.56107287871968], [-0.885457870533961, 51.5606602434964], [-0.885606584631741, 51.56059601575753], [-0.88578613479336, 51.56050960117672], [-0.88595858283258, 51.56041862303493], [-0.886091760097573, 51.560340759581955], [-0.886521253482028, 51.56006159461465], [-0.886883345687433, 51.559824949307504], [-0.887389733197074, 51.559468282123994], [-0.887580604245187, 51.55927227271282], [-0.887708691217493, 51.559107139161064], [-0.888191015763102, 51.55861266662589], [-0.888192457957821, 51.55861268028735], [-0.888287760756616, 51.55849039596854], [-0.888562664893145, 51.558278995716826], [-0.888677108662246, 51.55814070717499], [-0.888887527216288, 51.55791161122132], [-0.889030158653071, 51.55774121885465], [-0.889203011709727, 51.557514464273005], [-0.88945350380216, 51.55717964382524], [-0.889600043815338, 51.556967026485395], [-0.889736358446423, 51.55670036168757], [-0.889858423154084, 51.55648571413559], [-0.889957478394766, 51.55626815130874], [-0.88999480235023, 51.556157006507235], [-0.890171676314085, 51.5555274577222], [-0.89040150985715, 51.554855248874496], [-0.891496918227321, 51.55316795557777], [-0.892148150167392, 51.55212836271704], [-0.892302414411729, 51.5517746441604], [-0.892679622502675, 51.55097074336506], [-0.892968782461996, 51.55046633574481], [-0.893655961353766, 51.54930928124159], [-0.894173495307085, 51.548604708475054], [-0.894625223197592, 51.54805597035748], [-0.895275002004698, 51.547308578527485], [-0.895581553072133, 51.54691762432374], [-0.89567259455686, 51.54679079793778], [-0.895853734572665, 51.54651645501248], [-0.896746527292651, 51.54508077321264], [-0.896901839906062, 51.544860136456265], [-0.897255891587921, 51.54494888564188], [-0.898115394177492, 51.545187148067974], [-0.89822539056202, 51.54523044209882], [-0.898280925208036, 51.54525973711452], [-0.898317695099433, 51.54528975512979], [-0.898473190139101, 51.54530020648797], [-0.899619101095523, 51.54544313546729], [-0.901006352145532, 51.54562517973134], [-0.901825064903737, 51.54570208025918], [-0.903152296119515, 51.54586195719927], [-0.903215411109321, 51.54587603470979], [-0.903297183099556, 51.545893883241035], [-0.903017403675823, 51.54655396139701], [-0.902616538461231, 51.54745118838641], [-0.902395351374664, 51.54801290343283], [-0.902224993241029, 51.54837997226972], [-0.902166365216381, 51.54859882282856], [-0.902146545476892, 51.54876318664974], [-0.902208891983797, 51.54892921824649], [-0.902230894835185, 51.549033728477525], [-0.902380735585514, 51.54999904656443], [-0.902673692529055, 51.551610411429984], [-0.902806620567669, 51.55250003963136], [-0.902816651036337, 51.55268266601908], [-0.902804979597758, 51.55292803179951], [-0.902756997764027, 51.55318384821566], [-0.902654701329301, 51.55353896524768], [-0.902427419928527, 51.55423280167036], [-0.901847751389036, 51.555843197130926], [-0.901770133963284, 51.556011515784924], [-0.90172081219273, 51.556082988265544], [-0.902203201151337, 51.55617741874876], [-0.906010818638152, 51.55679743475821], [-0.906204734572883, 51.556771367660915], [-0.906311884484255, 51.55675438267928], [-0.906358975073264, 51.55689599188705], [-0.90638590166065, 51.55691602462513], [-0.906615524939952, 51.55696492104195], [-0.907278267614382, 51.55705831304524], [-0.907858939004531, 51.55720578727805], [-0.908174621569804, 51.5572752632291], [-0.908339760107985, 51.55730647205926], [-0.908420198492941, 51.557320707807335], [-0.908923514869315, 51.557385632424236], [-0.909322889103033, 51.5574540848968], [-0.909506497855653, 51.557497152980005], [-0.909658336207082, 51.557541723987356], [-0.909754316957776, 51.55756959081508], [-0.909871264277585, 51.557625526703404], [-0.91002439519459, 51.55767640345812], [-0.91014009429463, 51.557724234915874], [-0.910363938659539, 51.55783421414451], [-0.910769828656022, 51.55805288423369], [-0.910899633150579, 51.55817457810929], [-0.911134211672749, 51.55843931338367], [-0.911191431662737, 51.558519870694006], [-0.911262279817118, 51.55863382382822], [-0.911345597527786, 51.558829717406], [-0.911347039740573, 51.55882973078292], [-0.911354152248679, 51.55895478193117], [-0.911501156990394, 51.55932300828838], [-0.911744284152759, 51.55977395051585], [-0.911784714781588, 51.55983277167005], [-0.911848028397377, 51.559899897522016], [-0.911951124589094, 51.55999256899618], [-0.912043240814804, 51.56006176008463], [-0.912343203354435, 51.560247072388215], [-0.91252735254784, 51.560389049785144], [-0.912663001694362, 51.56050809825428], [-0.913644040185922, 51.561715780647766], [-0.914729932802775, 51.56149024267299], [-0.915936249212879, 51.561720788632314], [-0.917099342153636, 51.56255696600573], [-0.917716153850379, 51.56209778262442], [-0.918510926061236, 51.561494569835055], [-0.919190082061234, 51.56187308324347], [-0.919265061021478, 51.56187467281339], [-0.919319677161742, 51.561883268238525], [-0.919395565855925, 51.56190734542486], [-0.919450182060758, 51.561915940789575], [-0.919451624375034, 51.56191595406745], [-0.919612764956992, 51.561873377936905], [-0.919684473323871, 51.562134798108005], [-0.919731696029427, 51.56227280618616], [-0.919795125391412, 51.562396576626476], [-0.919877773921036, 51.56250074208832], [-0.920024454979703, 51.56264236275641], [-0.920273793481437, 51.562835281288635], [-0.920455811890565, 51.56300779833283], [-0.92054707457537, 51.56311384087594], [-0.920622684574115, 51.56321074767881], [-0.920768557091237, 51.56344767224896], [-0.920815933327546, 51.56357938704838], [-0.92087756775181, 51.56365728255545], [-0.920897207761338, 51.56368084160506], [-0.920950783915168, 51.5637334861553], [-0.921113636188415, 51.563862665653886], [-0.921195103215065, 51.56395602921301], [-0.921351882125165, 51.56422002842434], [-0.921395592904906, 51.56432383493418], [-0.921420893006769, 51.56441308549212], [-0.921438619701684, 51.56451755238376], [-0.921413985191466, 51.56464410933019], [-0.92167481147157, 51.56453500840272], [-0.923479752756133, 51.56373602685831], [-0.924155377789785, 51.5634113259626], [-0.924873111301507, 51.56399247344971], [-0.924951149378637, 51.56404803772923], [-0.925274524870032, 51.56428388466152], [-0.92664770764064, 51.56515336065692], [-0.927393574791524, 51.56558368874587], [-0.927927453464337, 51.5659491340051], [-0.92835633038721, 51.56599441223158], [-0.928244524844939, 51.56725223174753], [-0.928125342518282, 51.56741209518939], [-0.9281054698832, 51.56745956981058], [-0.927839528670842, 51.568092855254655], [-0.93052584537502, 51.568532778436946], [-0.930434864440691, 51.56872077542371], [-0.930290537945866, 51.568968530677175], [-0.93032458943141, 51.568993118606556], [-0.930407160146686, 51.56904062792432], [-0.930494248489543, 51.56908008580425], [-0.93056005729139, 51.5691040638391], [-0.930644619283805, 51.56912821268005], [-0.930755210497826, 51.569149901051155], [-0.931002865082897, 51.56917193845677], [-0.931506345671459, 51.5692367670135], [-0.9319179887186, 51.56928007686346], [-0.93222706378822, 51.569328746497334], [-0.932389335623021, 51.56936169347699], [-0.932508352034028, 51.56939334769875], [-0.932608510110525, 51.56942932617174], [-0.932871163025979, 51.56955040480943], [-0.933086053531851, 51.569616199317096], [-0.933414865356232, 51.569684826955594], [-0.93386895042082, 51.56976448240679], [-0.934635570791928, 51.5700537823344], [-0.934785550106084, 51.57011898456062], [-0.934985327167408, 51.57021431104797], [-0.935122135234023, 51.5702874858722], [-0.935333952219633, 51.570423383659445], [-0.935683954424458, 51.570697207984594], [-0.935948857561102, 51.57084617434456], [-0.936321009353978, 51.57109861741231], [-0.936776166293208, 51.57138058458356], [-0.936874033955222, 51.57139136186155], [-0.937185388877335, 51.57140497135624], [-0.937358713203379, 51.57139754881963], [-0.937474500211682, 51.571382411871916], [-0.937604964789291, 51.57135661760672], [-0.938082770631526, 51.571224267138255], [-0.938303744516349, 51.57115343316592], [-0.938622419406116, 51.57103852370375], [-0.938583754985448, 51.57127375671787], [-0.938615426417796, 51.5714008261012], [-0.938651384040882, 51.57152973256723], [-0.938810396393867, 51.572013125409214], [-0.938917102284257, 51.5723881447753], [-0.938977920287056, 51.572564931845086], [-0.939147081147104, 51.57298457478389], [-0.93921529881351, 51.57340150695511], [-0.939295227462625, 51.57374930879435], [-0.939359853061118, 51.57401065198471]]]}}
diff --git a/benchmarks/parse.py b/benchmarks/parse.py
--- a/benchmarks/parse.py
+++ b/benchmarks/parse.py
@@ -2,6 +2,16 @@
 
 import json, sys, time
 
+def isint(x):
+    try:
+        int(x)
+        return True
+    except:
+        return False
+
+if len(sys.argv) > 2 and isint(sys.argv[1]) and isint(sys.argv[2]):
+    sys.argv.pop(1)
+
 count = int(sys.argv[1])
 
 for n in sys.argv[2:]:
@@ -12,4 +22,4 @@
         fp.seek(0)
         val = json.load(fp)
     end = time.time()
-    print ' ', end - start
+    print '  %d good, %gs' % (count, end - start)
diff --git a/changelog b/changelog
new file mode 100644
--- /dev/null
+++ b/changelog
@@ -0,0 +1,119 @@
+0.7.0.0
+
+	* The performance of encoding to and decoding of bytestrings
+	  have both improved by up to 2x, while also using less
+	  memory.
+
+	* New dependency: the scientific package lets us parse
+	  floating point numbers more quickly and accurately.
+
+	* eitherDecode, decodeStrictWith: fixed bugs.
+
+	* Added FromJSON and ToJSON instances for Tree and Scientific.
+
+	* Fixed the ToJSON instances for UTCTime and ZonedTime.
+
+0.6 series
+
+	* Much improved documentation.
+
+	* Angle brackets are now escaped in JSON strings, to help avoid XSS
+	  attacks.
+
+	* Fixed up handling of nullary constructors when using generic
+	  encoding.
+
+	* Added ToJSON/FromJSON instances for:
+
+	  * The Fixed class
+	  * ISO-8601 dates: UTCTime, ZonedTime, and TimeZone
+
+	* Added accessor functions for inspecting Values.
+
+	* Added eitherDecode function that returns an error message if
+	  decoding fails.
+
+0.5 to 0.6
+
+	* This release introduces a slightly obscure, but
+	  backwards-incompatible, change.
+
+	  In the generic APIs of versions 0.4 and 0.5, fields whose
+	  names began with a "_" character would have this character
+	  removed.  This no longer occurs, as it was both buggy and
+	  surprising (https://github.com/bos/aeson/issues/53).
+
+	* Fixed a bug in generic decoding of nullary constructors
+	  (https://github.com/bos/aeson/issues/62).
+
+0.4 to 0.5
+
+	* When used with the UTF-8 encoding performance improvements
+	  introduced in version 0.11.1.12 of the text package, this
+	  release improves aeson's JSON encoding performance by 33%
+	  relative to aeson 0.4.
+
+	  As part of achieving this improvement, an API change was
+	  necessary.  The fromValue function in the
+	  Data.Aeson.Encode module now uses the text package's
+	  Builder type instead of the blaze-builder package's
+	  Builder type.
+
+0.3 to 0.4
+
+	* The new decode function complements the longstanding
+	  encode function, and makes the API simpler.
+
+	* New examples make it easier to learn to use the package
+	  (https://github.com/bos/aeson/tree/master/examples).
+
+	* Generics support
+
+	  aeson's support for data-type generic programming makes it
+	  possible to use JSON encodings of most data types without
+	  writing any boilerplate instances.
+
+	  Thanks to Bas Van Dijk, aeson now supports the two major
+	  schemes for doing datatype-generic programming:
+
+	  * the modern mechanism, built into GHC itself
+	    (http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-programming.html)
+
+	  * the older mechanism, based on SYB (aka "scrap your
+	    boilerplate")
+
+	  The modern GHC-based generic mechanism is fast and terse: in
+	  fact, its performance is generally comparable in performance
+	  to hand-written and TH-derived ToJSON and FromJSON
+	  instances.  To see how to use GHC generics, refer to
+	  examples/Generic.hs.
+
+	  The SYB-based generics support lives in Data.Aeson.Generic
+	  and is provided mainly for users of GHC older than 7.2.  SYB
+	  is far slower (by about 10x) than the more modern generic
+	  mechanism.  To see how to use SYB generics, refer to
+	  examples/GenericSYB.hs.
+
+	* We switched the intermediate representation of JSON objects
+	  from Data.Map to Data.HashMap which has improved type
+	  conversion performance.
+
+	* Instances of ToJSON and FromJSON for tuples are between 45%
+	  and 70% faster than in 0.3.
+
+	* Evaluation control
+
+	  This version of aeson makes explicit the decoupling between
+	  *identifying* an element of a JSON document and *converting*
+	  it to Haskell.  See the Data.Aeson.Parser documentation for
+	  details.
+
+	  The normal aeson decode function performs identification
+	  strictly, but defers conversion until needed.  This can
+	  result in improved performance (e.g. if the results of some
+	  conversions are never needed), but at a cost in increased
+	  memory consumption.
+
+	  The new decode' function performs identification and
+	  conversion immediately.  This incurs an up-front cost in CPU
+	  cycles, but reduces reduce memory consumption.
diff --git a/release-notes.markdown b/release-notes.markdown
deleted file mode 100644
--- a/release-notes.markdown
+++ /dev/null
@@ -1,113 +0,0 @@
-# 0.6 series
-
-Much improved documentation.
-
-Angle brackets are now escaped in JSON strings, to help avoid XSS
-attacks.
-
-Fixed up handling of nullary constructors when using generic encoding.
-
-Added ToJSON/FromJSON instances for:
-
-* The `Fixed` class
-
-* ISO-8601 dates: `UTCTime`, `ZonedTime`, and `TimeZone`
-
-Added accessor functions for inspecting `Value`s.
-
-Added `eitherDecode` function that returns an error message if
-decoding fails.
-
-# 0.5 to 0.6
-
-This release introduces a slightly obscure, but
-backwards-incompatible, change.
-
-In the generic APIs of versions 0.4 and 0.5, fields whose names began
-with a "`_`" character would have this character removed.  This no
-longer occurs, as [it was both buggy and
-surprising](https://github.com/bos/aeson/issues/53).
-
-Also:
-
-* Fixed [a bug in generic decoding of nullary constructors](https://github.com/bos/aeson/issues/62)
-
-# 0.4 to 0.5
-
-When used with the UTF-8 encoding performance improvements introduced
-in version 0.11.1.12 of the text package, this release improves
-aeson's JSON encoding performance by 33% relative to aeson 0.4.
-
-As part of achieving this improvement, an API change was necessary.
-The `fromValue` function in the `Data.Aeson.Encode` module now uses
-the text package's `Builder` type instead of the blaze-builder
-package's `Builder` type.
-
-# 0.3 to 0.4
-
-## Ease of use
-
-The new [`decode`
-function](http://hackage.haskell.org/packages/archive/aeson/latest/doc/html/Data-Aeson.html#v:decode)
-complements the longstanding `encode` function, and makes the API
-simpler.
-
-[New examples](https://github.com/bos/aeson/tree/master/examples) make
-it easier to learn to use the package.
-
-
-## Generics support
-
-aeson's support for data-type generic programming makes it possible to
-use JSON encodings of most data types without writing any boilerplate
-instances.
-
-Thanks to Bas Van Dijk, aeson now supports the two major schemes for
-doing datatype-generic programming:
-
-* the modern mechanism, [built into GHC
-  itself](http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-programming.html)
-
-* the older mechanism, based on SYB (aka "scrap your boilerplate")
-
-The modern GHC-based generic mechanism is fast and terse: in fact, its
-performance is generally comparable in performance to hand-written and
-TH-derived `ToJSON` and `FromJSON` instances.  To see how to use GHC
-generics, refer to
-[`examples/Generic.hs`](https://github.com/bos/aeson/blob/master/examples/Generic.hs).
-
-The SYB-based generics support lives in
-[Data.Aeson.Generic](http://hackage.haskell.org/packages/archive/aeson/latest/doc/html/Data-Aeson-Generic.html),
-and is provided mainly for users of GHC older than 7.2.  SYB is far
-slower (by about 10x) than the more modern generic mechanism.  To see
-how to use SYB generics, refer to
-[`examples/GenericSYB.hs`](https://github.com/bos/aeson/blob/master/examples/GenericSYB.hs).
-
-
-## Improved performance
-
-* We switched the intermediate representation of JSON objects from
-  `Data.Map` to
-  [`Data.HashMap`](http://hackage.haskell.org/package/unordered-containers),
-  which has improved type conversion performance.
-
-* Instances of `ToJSON` and `FromJSON` for tuples are between 45% and
-  70% faster than in 0.3.
-
-
-## Evaluation control
-
-This version of aeson makes explicit the decoupling between
-*identifying* an element of a JSON document and *converting* it to
-Haskell.  See the
-[`Data.Aeson.Parser`](http://hackage.haskell.org/packages/archive/aeson/latest/doc/html/Data-Aeson-Parser.html)
-documentation for details.
-
-The normal aeson `decode` function performs identification strictly,
-but defers conversion until needed.  This can result in improved
-performance (e.g. if the results of some conversions are never
-needed), but at a cost in increased memory consumption.
-
-The new `decode'` function performs identification and conversion
-immediately.  This incurs an up-front cost in CPU cycles, but reduces
-reduce memory consumption.
diff --git a/tests/Instances.hs b/tests/Instances.hs
--- a/tests/Instances.hs
+++ b/tests/Instances.hs
@@ -40,7 +40,8 @@
     arbitrary = ModifiedJulianDay `liftM` arbitrary
 
 instance Arbitrary DiffTime where
-    arbitrary = picosecondsToDiffTime `liftM` choose (0, 86400000000000000)
+    arbitrary = (picosecondsToDiffTime . (* 1000000000)) <$>
+                choose (0, 86400000)
 
 instance Arbitrary UTCTime where
     arbitrary = liftM2 UTCTime arbitrary arbitrary
diff --git a/tests/Properties.hs b/tests/Properties.hs
--- a/tests/Properties.hs
+++ b/tests/Properties.hs
@@ -1,16 +1,21 @@
 {-# LANGUAGE CPP, OverloadedStrings, RecordWildCards, ScopedTypeVariables #-}
 
+import Control.Monad (forM)
+import Data.Aeson (eitherDecode)
 import Data.Aeson.Encode
 import Data.Aeson.Parser (value)
 import Data.Aeson.Types
-import Data.Attoparsec.Number
 import Test.Framework (Test, defaultMain, testGroup)
 import Test.Framework.Providers.QuickCheck2 (testProperty)
+import Test.Framework.Providers.HUnit (testCase)
+import Test.HUnit                     (assertFailure, assertEqual)
 import Test.QuickCheck (Arbitrary(..))
 import qualified Data.Vector as V
 import qualified Data.Attoparsec.Lazy as L
 import qualified Data.ByteString.Lazy.Char8 as L
 import qualified Data.Text as T
+import qualified Data.Text.Lazy.Builder as TLB
+import qualified Data.Text.Lazy.Encoding as TLE
 import qualified Data.HashMap.Strict as H
 import Data.Time.Clock (UTCTime(..))
 import Data.Time (ZonedTime(..))
@@ -23,15 +28,22 @@
 import qualified Data.Map as Map
 #endif
 
+{-
+roundTripCaml :: String -> Bool
+roundTripCaml s = s == (camlFrom '_' $ camlTo '_' s)
+  where
+    camlFrom :: Char -> String -> String
+    camlFrom c = concatMap capitalize $ split c
+-}
 
 encodeDouble :: Double -> Double -> Bool
 encodeDouble num denom
-    | isInfinite d || isNaN d = encode (Number (D d)) == "null"
-    | otherwise               = (read . L.unpack . encode . Number . D) d == d
+    | isInfinite d || isNaN d = encode d == "null"
+    | otherwise               = (read . L.unpack . encode) d == d
   where d = num / denom
 
 encodeInteger :: Integer -> Bool
-encodeInteger i = encode (Number (I i)) == L.pack (show i)
+encodeInteger i = encode i == L.pack (show i)
 
 toParseJSON :: (Arbitrary a, Eq a) => (Value -> Parser a) -> (a -> Value) -> a -> Bool
 toParseJSON parsejson tojson x =
@@ -62,7 +74,9 @@
     result = parse parser ()
 
 main :: IO ()
-main = defaultMain tests
+main = do
+    comparisonTest <- encoderComparisonTests
+    defaultMain (comparisonTest : tests)
 
 #ifdef GHC_GENERICS
 type P6 = Product6 Int Bool String (Approx Double) (Int, Approx Double) ()
@@ -102,6 +116,10 @@
       testProperty "encodeDouble" encodeDouble
     , testProperty "encodeInteger" encodeInteger
     ],
+  -- testGroup "camlCase" [
+  --     testProperty "camlTo" $ roundTripCaml "AnApiMethod"
+  --   , testProperty "camlTo" $ roundTripCaml "anotherMethodType"
+  --   ],
   testGroup "roundTrip" [
       testProperty "Bool" $ roundTripEq True
     , testProperty "Double" $ roundTripEq (1 :: Approx Double)
@@ -110,8 +128,8 @@
     , testProperty "String" $ roundTripEq (""::String)
     , testProperty "Text" $ roundTripEq T.empty
     , testProperty "Foo" $ roundTripEq (undefined::Foo)
-    , testProperty "DotNetTime" $ roundTripEq (undefined :: Approx DotNetTime)
-    , testProperty "UTCTime" $ roundTripEq (undefined :: Approx UTCTime)
+    , testProperty "DotNetTime" $ roundTripEq (undefined :: DotNetTime)
+    , testProperty "UTCTime" $ roundTripEq (undefined :: UTCTime)
     , testProperty "ZonedTime" $ roundTripEq (undefined::ZonedTime)
 #ifdef GHC_GENERICS
     , testGroup "ghcGenerics" [
@@ -198,3 +216,38 @@
     ]
 #endif
   ]
+
+
+------------------------------------------------------------------------------
+-- Comparison between bytestring and text encoders
+------------------------------------------------------------------------------
+
+encoderComparisonTests :: IO Test
+encoderComparisonTests = do
+    encoderTests <- forM testFiles $ \file0 -> do
+        let file = "benchmarks/json-data/" ++ file0
+        return $ testCase file $ do
+            inp <- L.readFile file
+            case eitherDecode inp of
+              Left  err -> assertFailure $ "Decoding failure: " ++ err
+              Right val -> assertEqual "" (encode val) (encodeViaText val)
+    return $ testGroup "Compare bytestring and text encoders" encoderTests
+  where
+    encodeViaText :: Value -> L.ByteString
+    encodeViaText =
+        TLE.encodeUtf8 . TLB.toLazyText . encodeToTextBuilder . toJSON
+
+    testFiles =
+      [ "example.json"
+      , "integers.json"
+      , "jp100.json"
+      , "numbers.json"
+      , "twitter10.json"
+      , "twitter20.json"
+      , "geometry.json"
+      , "jp10.json"
+      , "jp50.json"
+      , "twitter1.json"
+      , "twitter100.json"
+      , "twitter50.json"
+      ]
