diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+2.7
+---
+
+- Upgrade `aeson` to `2.0.1.0` (see [#228]( https://github.com/GetShopTV/swagger2/pull/228 ));
+- Switch from Travis CI to GitHub Actions (see [#228]( https://github.com/GetShopTV/swagger2/pull/228 ));
+- GHC 9 support (see [#228]( https://github.com/GetShopTV/swagger2/pull/228 ));
+- More GHC-8.10 related cleanup, tighten lower bound on some dependencies.
+  (see [#216]( https://github.com/GetShopTV/swagger2/pull/216 ));
+- Add "format" field for uint32 and uint64
+  (see [#215]( https://github.com/GetShopTV/swagger2/pull/215 ));
+
 2.6
 ---
 
diff --git a/include/overlapping-compat.h b/include/overlapping-compat.h
deleted file mode 100644
--- a/include/overlapping-compat.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#if __GLASGOW_HASKELL__ >= 710
-#define OVERLAPPABLE_ {-# OVERLAPPABLE #-}
-#define OVERLAPPING_  {-# OVERLAPPING #-}
-#else
-{-# LANGUAGE OverlappingInstances #-}
-#define OVERLAPPABLE_
-#define OVERLAPPING_
-#endif
diff --git a/src/Data/Swagger.hs b/src/Data/Swagger.hs
--- a/src/Data/Swagger.hs
+++ b/src/Data/Swagger.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 -- |
 -- Module:      Data.Swagger
 -- Maintainer:  Nickolay Kudasov <nickolay@getshoptv.com>
@@ -145,7 +144,7 @@
 -- In this library you can use @'mempty'@ for a default/empty value. For instance:
 --
 -- >>> encode (mempty :: Swagger)
--- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"}}"
+-- "{\"swagger\":\"2.0\",\"info\":{\"title\":\"\",\"version\":\"\"}}"
 --
 -- As you can see some spec properties (e.g. @"version"@) are there even when the spec is empty.
 -- That is because these properties are actually required ones.
@@ -154,12 +153,12 @@
 -- although it is not strictly necessary:
 --
 -- >>> encode mempty { _infoTitle = "Todo API", _infoVersion = "1.0" }
--- "{\"version\":\"1.0\",\"title\":\"Todo API\"}"
+-- "{\"title\":\"Todo API\",\"version\":\"1.0\"}"
 --
 -- You can merge two values using @'mappend'@ or its infix version @('<>')@:
 --
 -- >>> encode $ mempty { _infoTitle = "Todo API" } <> mempty { _infoVersion = "1.0" }
--- "{\"version\":\"1.0\",\"title\":\"Todo API\"}"
+-- "{\"title\":\"Todo API\",\"version\":\"1.0\"}"
 --
 -- This can be useful for combining specifications of endpoints into a whole API specification:
 --
@@ -193,7 +192,7 @@
 --         & at 200 ?~ ("OK" & _Inline.schema ?~ Ref (Reference "User"))
 --         & at 404 ?~ "User info not found")) ]
 -- :}
--- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"},\"paths\":{\"/user\":{\"get\":{\"produces\":[\"application/json\"],\"responses\":{\"404\":{\"description\":\"User info not found\"},\"200\":{\"schema\":{\"$ref\":\"#/definitions/User\"},\"description\":\"OK\"}}}}},\"definitions\":{\"User\":{\"type\":\"string\"}}}"
+-- "{\"swagger\":\"2.0\",\"info\":{\"title\":\"\",\"version\":\"\"},\"paths\":{\"/user\":{\"get\":{\"produces\":[\"application/json\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"$ref\":\"#/definitions/User\"}},\"404\":{\"description\":\"User info not found\"}}}}},\"definitions\":{\"User\":{\"type\":\"string\"}}}"
 --
 -- In the snippet above we declare an API with a single path @/user@. This path provides method @GET@
 -- which produces @application/json@ output. It should respond with code @200@ and body specified
@@ -295,38 +294,18 @@
 --
 -- we can not derive a valid schema for a mix of the above. The following will result in a type error
 --
-#if __GLASGOW_HASKELL__ < 800
 -- >>> data BadMixedType = ChoiceBool Bool | JustTag deriving Generic
 -- >>> instance ToSchema BadMixedType
 -- ...
 -- ... error:
--- ... • No instance for (Data.Swagger.Internal.TypeShape.CannotDeriveSchemaForMixedSumType
--- ...                      BadMixedType)
--- ...     arising from a use of ‘Data.Swagger.Internal.Schema.$dmdeclareNamedSchema’
--- ... • In the expression:
--- ...     Data.Swagger.Internal.Schema.$dmdeclareNamedSchema @BadMixedType
--- ...   In an equation for ‘declareNamedSchema’:
--- ...       declareNamedSchema
--- ...         = Data.Swagger.Internal.Schema.$dmdeclareNamedSchema @BadMixedType
--- ...   In the instance declaration for ‘ToSchema BadMixedType’
-#else
--- >>> data BadMixedType = ChoiceBool Bool | JustTag deriving Generic
--- >>> instance ToSchema BadMixedType
--- ...
--- ... error:
 -- ... • Cannot derive Generic-based Swagger Schema for BadMixedType
 -- ...   BadMixedType is a mixed sum type (has both unit and non-unit constructors).
 -- ...   Swagger does not have a good representation for these types.
 -- ...   Use genericDeclareNamedSchemaUnrestricted if you want to derive schema
 -- ...   that matches aeson's Generic-based toJSON,
 -- ...   but that's not supported by some Swagger tools.
--- ... • In the expression:
--- ...     Data.Swagger.Internal.Schema.$dmdeclareNamedSchema @BadMixedType
--- ...   In an equation for ‘declareNamedSchema’:
--- ...       declareNamedSchema
--- ...         = Data.Swagger.Internal.Schema.$dmdeclareNamedSchema @BadMixedType
--- ...   In the instance declaration for ‘ToSchema BadMixedType’
-#endif
+-- ...
+-- ... In the instance declaration for ‘ToSchema BadMixedType’
 --
 -- We can use 'genericDeclareNamedSchemaUnrestricted' to try our best to represent this type as a Swagger Schema and match 'ToJSON':
 --
diff --git a/src/Data/Swagger/Declare.hs b/src/Data/Swagger/Declare.hs
--- a/src/Data/Swagger/Declare.hs
+++ b/src/Data/Swagger/Declare.hs
@@ -60,7 +60,7 @@
     return (mappend d' d'', y)
 
 instance Monoid d => MonadTrans (DeclareT d) where
-  lift m = DeclareT (\_ -> (,) mempty `liftM` m)
+  lift m = DeclareT (\_ -> (,) mempty <$> m)
 
 -- |
 -- Definitions of @declare@ and @look@ must satisfy the following laws:
@@ -103,12 +103,12 @@
 -- | Evaluate @'DeclareT' d m a@ computation,
 -- ignoring new output @d@.
 evalDeclareT :: Monad m => DeclareT d m a -> d -> m a
-evalDeclareT (DeclareT f) d = snd `liftM` f d
+evalDeclareT (DeclareT f) d = snd <$> f d
 
 -- | Execute @'DeclateT' d m a@ computation,
 -- ignoring result and only producing new output @d@.
 execDeclareT :: Monad m => DeclareT d m a -> d -> m d
-execDeclareT (DeclareT f) d = fst `liftM` f d
+execDeclareT (DeclareT f) d = fst <$> f d
 
 -- | Evaluate @'DeclareT' d m a@ computation,
 -- starting with empty output history.
diff --git a/src/Data/Swagger/Internal.hs b/src/Data/Swagger/Internal.hs
--- a/src/Data/Swagger/Internal.hs
+++ b/src/Data/Swagger/Internal.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveFunctor #-}
@@ -15,10 +14,6 @@
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}
-#if __GLASGOW_HASKELL__ <710
-{-# LANGUAGE PolyKinds #-}
-#endif
-#include "overlapping-compat.h"
 module Data.Swagger.Internal where
 
 import Prelude ()
@@ -47,6 +42,7 @@
 
 import           Data.HashMap.Strict.InsOrd (InsOrdHashMap)
 import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
+import qualified Data.Aeson.KeyMap          as KM
 
 import Generics.SOP.TH                  (deriveGeneric)
 import Data.Swagger.Internal.AesonUtils (sopSwaggerGenericToJSON
@@ -58,13 +54,7 @@
                                         ,saoAdditionalPairs
                                         ,saoSubObject)
 import Data.Swagger.Internal.Utils
-
-#if MIN_VERSION_aeson(0,10,0)
 import Data.Swagger.Internal.AesonUtils (sopSwaggerGenericToEncoding)
-#define DEFINE_TOENCODING toEncoding = sopSwaggerGenericToEncoding
-#else
-#define DEFINE_TOENCODING
-#endif
 
 -- $setup
 -- >>> :seti -XDataKinds
@@ -416,7 +406,7 @@
   dataTypeOf _ = swaggerItemsDataType
 
 instance Data (SwaggerItems 'SwaggerKindSchema) where
-  gfoldl _ _ (SwaggerItemsPrimitive _ _) = error $ " Data.Data.gfoldl: Constructor SwaggerItemsPrimitive used to construct SwaggerItems SwaggerKindSchema"
+  gfoldl _ _ (SwaggerItemsPrimitive _ _) = error " Data.Data.gfoldl: Constructor SwaggerItemsPrimitive used to construct SwaggerItems SwaggerKindSchema"
   gfoldl k z (SwaggerItemsObject ref)    = z SwaggerItemsObject `k` ref
   gfoldl k z (SwaggerItemsArray ref)     = z SwaggerItemsArray `k` ref
 
@@ -832,6 +822,23 @@
   | AdditionalPropertiesSchema (Referenced Schema)
   deriving (Eq, Show, Data, Typeable)
 
+-------------------------------------------------------------------------------
+-- Generic instances
+-------------------------------------------------------------------------------
+
+deriveGeneric ''Header
+deriveGeneric ''OAuth2Params
+deriveGeneric ''Operation
+deriveGeneric ''Param
+deriveGeneric ''ParamOtherSchema
+deriveGeneric ''PathItem
+deriveGeneric ''Response
+deriveGeneric ''Responses
+deriveGeneric ''SecurityScheme
+deriveGeneric ''Schema
+deriveGeneric ''ParamSchema
+deriveGeneric ''Swagger
+
 -- =======================================================================
 -- Monoid instances
 -- =======================================================================
@@ -928,7 +935,7 @@
      SecurityDefinitions $ InsOrdHashMap.unionWith (<>) sd1 sd2
 
 instance Monoid SecurityDefinitions where
-  mempty = SecurityDefinitions $ InsOrdHashMap.empty
+  mempty = SecurityDefinitions InsOrdHashMap.empty
   mappend = (<>)
 
 -- =======================================================================
@@ -959,7 +966,7 @@
   swaggerMempty = ParamQuery
   swaggerMappend _ y = y
 
-instance OVERLAPPING_ SwaggerMonoid (InsOrdHashMap FilePath PathItem) where
+instance {-# OVERLAPPING #-} SwaggerMonoid (InsOrdHashMap FilePath PathItem) where
   swaggerMempty = InsOrdHashMap.empty
   swaggerMappend = InsOrdHashMap.unionWith mappend
 
@@ -1060,7 +1067,7 @@
 
 instance ToJSON OAuth2Params where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON SecuritySchemeType where
   toJSON SecuritySchemeBasic
@@ -1073,20 +1080,23 @@
     <+> object [ "type" .= ("oauth2" :: Text) ]
 
 instance ToJSON Swagger where
-  toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toJSON a = sopSwaggerGenericToJSON a &
+    if InsOrdHashMap.null (_swaggerPaths a)
+    then (<+> object ["paths" .= object []])
+    else id
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON SecurityScheme where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON Schema where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON Header where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 -- | As for nullary schema for 0-arity type constructors, see
 -- <https://github.com/GetShopTV/swagger2/issues/167>.
@@ -1117,7 +1127,7 @@
 
 instance ToJSON Param where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON ParamAnySchema where
   toJSON (ParamBody s) = object [ "in" .= ("body" :: Text), "schema" .= s ]
@@ -1125,23 +1135,23 @@
 
 instance ToJSON ParamOtherSchema where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON Responses where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON Response where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON Operation where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON PathItem where
   toJSON = sopSwaggerGenericToJSON
-  DEFINE_TOENCODING
+  toEncoding = sopSwaggerGenericToEncoding
 
 instance ToJSON Example where
   toJSON = toJSON . Map.mapKeys show . getExample
@@ -1293,7 +1303,7 @@
 instance FromJSON Responses where
   parseJSON (Object o) = Responses
     <$> o .:? "default"
-    <*> (parseJSON (Object (HashMap.delete "default" o)))
+    <*> parseJSON (Object (KM.delete "default" o))
   parseJSON _ = empty
 
 instance FromJSON Example where
@@ -1366,23 +1376,6 @@
 instance FromJSON AdditionalProperties where
   parseJSON (Bool b) = pure $ AdditionalPropertiesAllowed b
   parseJSON js = AdditionalPropertiesSchema <$> parseJSON js
-
--------------------------------------------------------------------------------
--- TH splices
--------------------------------------------------------------------------------
-
-deriveGeneric ''Header
-deriveGeneric ''OAuth2Params
-deriveGeneric ''Operation
-deriveGeneric ''Param
-deriveGeneric ''ParamOtherSchema
-deriveGeneric ''PathItem
-deriveGeneric ''Response
-deriveGeneric ''Responses
-deriveGeneric ''SecurityScheme
-deriveGeneric ''Schema
-deriveGeneric ''ParamSchema
-deriveGeneric ''Swagger
 
 instance HasSwaggerAesonOptions Header where
   swaggerAesonOptions _ = mkSwaggerAesonOptions "header" & saoSubObject ?~ "paramSchema"
diff --git a/src/Data/Swagger/Internal/AesonUtils.hs b/src/Data/Swagger/Internal/AesonUtils.hs
--- a/src/Data/Swagger/Internal/AesonUtils.hs
+++ b/src/Data/Swagger/Internal/AesonUtils.hs
@@ -1,20 +1,15 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE ExplicitForAll #-}
 {-# LANGUAGE TemplateHaskell #-}
-#if __GLASGOW_HASKELL__ >= 800
 {-# LANGUAGE UndecidableSuperClasses #-}
-#endif
 module Data.Swagger.Internal.AesonUtils (
     -- * Generic functions
     AesonDefaultValue(..),
     sopSwaggerGenericToJSON,
-#if MIN_VERSION_aeson(0,10,0)
     sopSwaggerGenericToEncoding,
-#endif
     sopSwaggerGenericToJSONWithOpts,
     sopSwaggerGenericParseJSON,
     -- * Options
@@ -30,10 +25,17 @@
 import Prelude.Compat
 
 import Control.Applicative ((<|>))
-import Control.Lens     (makeLenses, (^.))
-import Control.Monad    (unless)
-import Data.Aeson       (ToJSON(..), FromJSON(..), Value(..), Object, object, (.:), (.:?), (.!=), withObject)
+import Control.Lens        (makeLenses, (^.))
+import Control.Monad       (unless)
+import Data.Aeson          ( Encoding, FromJSON (..), ToJSON (..)
+                           , Object, Series, Value (..)
+                           , object, pairs, withObject
+                           , (.!=), (.:), (.:?), (.=)
+                           )
+import Data.Aeson.Key   (fromString, toString, fromText, toText)
+import qualified Data.Aeson.KeyMap as KM
 import Data.Aeson.Types (Parser, Pair)
+import Data.Bifunctor   (first)
 import Data.Char        (toLower, isUpper)
 import Data.Foldable    (traverse_)
 import Data.Text        (Text)
@@ -46,10 +48,6 @@
 import qualified Data.HashMap.Strict.InsOrd as InsOrd
 import qualified Data.HashSet.InsOrd as InsOrdHS
 
-#if MIN_VERSION_aeson(0,10,0)
-import Data.Aeson (Encoding, pairs, (.=), Series)
-#endif
-
 -------------------------------------------------------------------------------
 -- SwaggerAesonOptions
 -------------------------------------------------------------------------------
@@ -112,7 +110,7 @@
     -> Value
 sopSwaggerGenericToJSON x =
     let ps = sopSwaggerGenericToJSON' opts (from x) (datatypeInfo proxy) (aesonDefaults proxy)
-    in object (opts ^. saoAdditionalPairs ++ ps)
+    in object $ (map $ first fromText) (opts ^. saoAdditionalPairs ++ (map $ first toText) ps)
   where
     proxy = Proxy :: Proxy a
     opts  = swaggerAesonOptions proxy
@@ -134,7 +132,7 @@
     -> Value
 sopSwaggerGenericToJSONWithOpts opts x =
     let ps = sopSwaggerGenericToJSON' opts (from x) (datatypeInfo proxy) defs
-    in object (opts ^. saoAdditionalPairs ++ ps)
+    in object $ (map $ first fromText) (opts ^. saoAdditionalPairs ++ (map $ first toText) ps)
   where
     proxy = Proxy :: Proxy a
     defs = hcpure (Proxy :: Proxy AesonDefaultValue) defaultValue
@@ -146,11 +144,7 @@
     -> DatatypeInfo '[xs]
     -> POP Maybe '[xs]
     -> [Pair]
-#if MIN_VERSION_generics_sop(0,5,0)
 sopSwaggerGenericToJSON' opts (SOP (Z fields)) (ADT _ _ (Record _ fieldsInfo :* Nil) _) (POP (defs :* Nil)) =
-#else
-sopSwaggerGenericToJSON' opts (SOP (Z fields)) (ADT _ _ (Record _ fieldsInfo :* Nil)) (POP (defs :* Nil)) =
-#endif
     sopSwaggerGenericToJSON'' opts fields fieldsInfo defs
 sopSwaggerGenericToJSON' _ _ _ _ = error "sopSwaggerGenericToJSON: unsupported type"
 
@@ -167,21 +161,18 @@
     go  Nil Nil Nil = []
     go (I x :* xs) (FieldInfo name :* names) (def :* defs)
         | Just name' == sub = case json of
-              Object m -> HM.toList m ++ rest
+              Object m -> KM.toList m ++ rest
               Null     -> rest
               _        -> error $ "sopSwaggerGenericToJSON: subjson is not an object: " ++ show json
         -- If default value: omit it.
         | Just x == def =
             rest
         | otherwise =
-            (T.pack name', json) : rest
+            (fromString name', json) : rest
       where
         json  = toJSON x
         name' = fieldNameModifier name
         rest  = go xs names defs
-#if __GLASGOW_HASKELL__ < 800
-    go _ _ _ = error "not empty"
-#endif
 
     fieldNameModifier = modifier . drop 1
     modifier = lowerFirstUppers . drop (length prefix)
@@ -213,7 +204,7 @@
 
     parseAdditionalField :: Object -> (Text, Value) -> Parser ()
     parseAdditionalField obj (k, v) = do
-        v' <- obj .: k
+        v' <- obj .: fromText k
         unless (v == v') $ fail $
             "Additonal field don't match for key " ++ T.unpack k
             ++ ": " ++ show v
@@ -226,11 +217,7 @@
     -> DatatypeInfo '[xs]
     -> POP Maybe '[xs]
     -> Parser (SOP I '[xs])
-#if MIN_VERSION_generics_sop(0,5,0)
 sopSwaggerGenericParseJSON' opts obj (ADT _ _ (Record _ fieldsInfo :* Nil) _) (POP (defs :* Nil)) =
-#else
-sopSwaggerGenericParseJSON' opts obj (ADT _ _ (Record _ fieldsInfo :* Nil)) (POP (defs :* Nil)) =
-#endif
     SOP . Z <$> sopSwaggerGenericParseJSON'' opts obj fieldsInfo defs
 sopSwaggerGenericParseJSON' _ _ _ _ = error "sopSwaggerGenericParseJSON: unsupported type"
 
@@ -248,10 +235,10 @@
     go (FieldInfo name :* names) (def :* defs)
         | Just name' == sub =
             -- Note: we might strip fields of outer structure.
-            cons <$> (withDef $ parseJSON $ Object obj) <*> rest
+            cons <$> withDef (parseJSON $ Object obj) <*> rest
         | otherwise = case def of
-            Just def' -> cons <$> obj .:? T.pack name' .!= def' <*> rest
-            Nothing  ->  cons <$> obj .: T.pack name' <*> rest
+            Just def' -> cons <$> obj .:? fromString name' .!= def' <*> rest
+            Nothing   -> cons <$> obj .:  fromString name' <*> rest
       where
         cons h t = I h :* t
         name' = fieldNameModifier name
@@ -260,9 +247,6 @@
         withDef = case def of
             Just def' -> (<|> pure def')
             Nothing   -> id
-#if __GLASGOW_HASKELL__ < 800
-    go _ _ = error "not empty"
-#endif
 
     fieldNameModifier = modifier . drop 1
     modifier = lowerFirstUppers . drop (length prefix)
@@ -273,8 +257,6 @@
 -- ToEncoding
 -------------------------------------------------------------------------------
 
-#if MIN_VERSION_aeson(0,10,0)
-
 sopSwaggerGenericToEncoding
     :: forall a xs.
         ( HasDatatypeInfo a
@@ -287,7 +269,7 @@
     -> Encoding
 sopSwaggerGenericToEncoding x =
     let ps = sopSwaggerGenericToEncoding' opts (from x) (datatypeInfo proxy) (aesonDefaults proxy)
-    in pairs (pairsToSeries (opts ^. saoAdditionalPairs) <> ps)
+    in pairs (pairsToSeries ((map $ first fromText) (opts ^. saoAdditionalPairs)) <> ps)
   where
     proxy = Proxy :: Proxy a
     opts  = swaggerAesonOptions proxy
@@ -302,11 +284,7 @@
     -> DatatypeInfo '[xs]
     -> POP Maybe '[xs]
     -> Series
-#if MIN_VERSION_generics_sop(0,5,0)
 sopSwaggerGenericToEncoding' opts (SOP (Z fields)) (ADT _ _ (Record _ fieldsInfo :* Nil) _) (POP (defs :* Nil)) =
-#else
-sopSwaggerGenericToEncoding' opts (SOP (Z fields)) (ADT _ _ (Record _ fieldsInfo :* Nil)) (POP (defs :* Nil)) =
-#endif
     sopSwaggerGenericToEncoding'' opts fields fieldsInfo defs
 sopSwaggerGenericToEncoding' _ _ _ _ = error "sopSwaggerGenericToEncoding: unsupported type"
 
@@ -323,24 +301,19 @@
     go  Nil Nil Nil = mempty
     go (I x :* xs) (FieldInfo name :* names) (def :* defs)
         | Just name' == sub = case toJSON x of
-              Object m -> pairsToSeries (HM.toList m) <> rest
+              Object m -> pairsToSeries (KM.toList m) <> rest
               Null     -> rest
               _        -> error $ "sopSwaggerGenericToJSON: subjson is not an object: " ++ show (toJSON x)
         -- If default value: omit it.
         | Just x == def =
             rest
         | otherwise =
-            (T.pack name' .= x) <> rest
+            (fromString name' .= x) <> rest
       where
         name' = fieldNameModifier name
         rest  = go xs names defs
-#if __GLASGOW_HASKELL__ < 800
-    go _ _ _ = error "not empty"
-#endif
 
     fieldNameModifier = modifier . drop 1
     modifier = lowerFirstUppers . drop (length prefix)
     lowerFirstUppers s = map toLower x ++ y
       where (x, y) = span isUpper s
-
-#endif
diff --git a/src/Data/Swagger/Internal/ParamSchema.hs b/src/Data/Swagger/Internal/ParamSchema.hs
--- a/src/Data/Swagger/Internal/ParamSchema.hs
+++ b/src/Data/Swagger/Internal/ParamSchema.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DefaultSignatures #-}
 {-# LANGUAGE FlexibleContexts #-}
@@ -12,13 +11,10 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE TypeSynonymInstances #-}
 {-# LANGUAGE UndecidableInstances #-}
-#if __GLASGOW_HASKELL__ >= 800
 -- Generic a is redundant in  ToParamSchema a default imple
 {-# OPTIONS_GHC -Wno-redundant-constraints #-}
 -- For TypeErrors
 {-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
-#endif
-#include "overlapping-compat.h"
 module Data.Swagger.Internal.ParamSchema where
 
 import Control.Lens
@@ -49,12 +45,9 @@
 import Data.Swagger.Lens
 import Data.Swagger.SchemaOptions
 
-#if __GLASGOW_HASKELL__ < 800
-#else
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Lazy as BSL
 import GHC.TypeLits (TypeError, ErrorMessage(..))
-#endif
 
 -- | Default schema for binary data (any sequence of octets).
 binaryParamSchema :: ParamSchema t
@@ -119,7 +112,7 @@
   default toParamSchema :: (Generic a, GToParamSchema (Rep a)) => Proxy a -> ParamSchema t
   toParamSchema = genericToParamSchema defaultSchemaOptions
 
-instance OVERLAPPING_ ToParamSchema String where
+instance {-# OVERLAPPING #-} ToParamSchema String where
   toParamSchema _ = mempty & type_ ?~ SwaggerString
 
 instance ToParamSchema Bool where
@@ -147,9 +140,13 @@
 instance ToParamSchema Word   where toParamSchema = toParamSchemaBoundedIntegral
 instance ToParamSchema Word8  where toParamSchema = toParamSchemaBoundedIntegral
 instance ToParamSchema Word16 where toParamSchema = toParamSchemaBoundedIntegral
-instance ToParamSchema Word32 where toParamSchema = toParamSchemaBoundedIntegral
-instance ToParamSchema Word64 where toParamSchema = toParamSchemaBoundedIntegral
 
+instance ToParamSchema Word32 where
+  toParamSchema proxy = toParamSchemaBoundedIntegral proxy & format ?~ "int32"
+
+instance ToParamSchema Word64 where
+  toParamSchema proxy = toParamSchemaBoundedIntegral proxy & format ?~ "int64"
+
 -- | Default plain schema for @'Bounded'@, @'Integral'@ types.
 --
 -- >>> encode $ toParamSchemaBoundedIntegral (Proxy :: Proxy Int8)
@@ -235,9 +232,6 @@
   toParamSchema _ = mempty
     & type_ ?~ SwaggerString
 
-
-#if __GLASGOW_HASKELL__ < 800
-#else
 type family ToParamSchemaByteStringError bs where
   ToParamSchemaByteStringError bs = TypeError
       ( 'Text "Impossible to have an instance " :<>: ShowType (ToParamSchema bs) :<>: Text "."
@@ -246,7 +240,6 @@
 
 instance ToParamSchemaByteStringError BS.ByteString  => ToParamSchema BS.ByteString  where toParamSchema = error "impossible"
 instance ToParamSchemaByteStringError BSL.ByteString => ToParamSchema BSL.ByteString where toParamSchema = error "impossible"
-#endif
 
 instance ToParamSchema All where toParamSchema _ = toParamSchema (Proxy :: Proxy Bool)
 instance ToParamSchema Any where toParamSchema _ = toParamSchema (Proxy :: Proxy Bool)
@@ -277,7 +270,7 @@
 
 -- |
 -- >>> encode $ toParamSchema (Proxy :: Proxy ())
--- "{\"type\":\"string\",\"enum\":[\"_\"]}"
+-- "{\"enum\":[\"_\"],\"type\":\"string\"}"
 instance ToParamSchema () where
   toParamSchema _ = mempty
     & type_ ?~ SwaggerString
@@ -293,7 +286,7 @@
 -- >>> :set -XDeriveGeneric
 -- >>> data Color = Red | Blue deriving Generic
 -- >>> encode $ genericToParamSchema defaultSchemaOptions (Proxy :: Proxy Color)
--- "{\"type\":\"string\",\"enum\":[\"Red\",\"Blue\"]}"
+-- "{\"enum\":[\"Red\",\"Blue\"],\"type\":\"string\"}"
 genericToParamSchema :: forall a t. (Generic a, GToParamSchema (Rep a)) => SchemaOptions -> Proxy a -> ParamSchema t
 genericToParamSchema opts _ = gtoParamSchema opts (Proxy :: Proxy (Rep a)) mempty
 
diff --git a/src/Data/Swagger/Internal/Schema.hs b/src/Data/Swagger/Internal/Schema.hs
--- a/src/Data/Swagger/Internal/Schema.hs
+++ b/src/Data/Swagger/Internal/Schema.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE DefaultSignatures #-}
 {-# LANGUAGE FlexibleContexts #-}
@@ -15,13 +14,9 @@
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE TypeSynonymInstances #-}
 {-# LANGUAGE UndecidableInstances #-}
-#if __GLASGOW_HASKELL__ >= 800
--- Few generics related redundant constraints
 {-# OPTIONS_GHC -Wno-redundant-constraints #-}
 -- For TypeErrors
 {-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
-#endif
-#include "overlapping-compat.h"
 module Data.Swagger.Internal.Schema where
 
 import Prelude ()
@@ -71,12 +66,11 @@
 import Data.Swagger.SchemaOptions
 import Data.Swagger.Internal.TypeShape
 
-#if __GLASGOW_HASKELL__ < 800
-#else
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Lazy as BSL
 import GHC.TypeLits (TypeError, ErrorMessage(..))
-#endif
+import qualified Data.Aeson.KeyMap as KM
+import Data.Aeson.Key (toText)
 
 unnamed :: Schema -> NamedSchema
 unnamed schema = NamedSchema Nothing schema
@@ -329,7 +323,7 @@
 -- >>> data Person = Person { name :: String, age :: Int } deriving (Generic)
 -- >>> instance ToJSON Person
 -- >>> encode $ sketchSchema (Person "Jack" 25)
--- "{\"required\":[\"age\",\"name\"],\"properties\":{\"age\":{\"type\":\"number\"},\"name\":{\"type\":\"string\"}},\"example\":{\"age\":25,\"name\":\"Jack\"},\"type\":\"object\"}"
+-- "{\"required\":[\"name\",\"age\"],\"properties\":{\"name\":{\"type\":\"string\"},\"age\":{\"type\":\"number\"}},\"example\":{\"age\":25,\"name\":\"Jack\"},\"type\":\"object\"}"
 sketchSchema :: ToJSON a => a -> Schema
 sketchSchema = sketch . toJSON
   where
@@ -353,7 +347,7 @@
         ischema = case ys of
           (z:_) | allSame -> Just z
           _               -> Nothing
-    go (Object o) = mempty
+    go (Object o') = let o = KM.toHashMapText o' in mempty
       & type_         ?~ SwaggerObject
       & required      .~ HashMap.keys o
       & properties    .~ fmap (Inline . go) (InsOrdHashMap.fromHashMap o)
@@ -362,18 +356,18 @@
 -- Produced schema uses as much constraints as possible.
 --
 -- >>> encode $ sketchStrictSchema "hello"
--- "{\"maxLength\":5,\"pattern\":\"hello\",\"minLength\":5,\"type\":\"string\",\"enum\":[\"hello\"]}"
+-- "{\"enum\":[\"hello\"],\"maxLength\":5,\"minLength\":5,\"pattern\":\"hello\",\"type\":\"string\"}"
 --
 -- >>> encode $ sketchStrictSchema (1, 2, 3)
--- "{\"minItems\":3,\"uniqueItems\":true,\"items\":[{\"maximum\":1,\"minimum\":1,\"multipleOf\":1,\"type\":\"number\",\"enum\":[1]},{\"maximum\":2,\"minimum\":2,\"multipleOf\":2,\"type\":\"number\",\"enum\":[2]},{\"maximum\":3,\"minimum\":3,\"multipleOf\":3,\"type\":\"number\",\"enum\":[3]}],\"maxItems\":3,\"type\":\"array\",\"enum\":[[1,2,3]]}"
+-- "{\"enum\":[[1,2,3]],\"items\":[{\"enum\":[1],\"maximum\":1,\"minimum\":1,\"multipleOf\":1,\"type\":\"number\"},{\"enum\":[2],\"maximum\":2,\"minimum\":2,\"multipleOf\":2,\"type\":\"number\"},{\"enum\":[3],\"maximum\":3,\"minimum\":3,\"multipleOf\":3,\"type\":\"number\"}],\"maxItems\":3,\"minItems\":3,\"type\":\"array\",\"uniqueItems\":true}"
 --
 -- >>> encode $ sketchStrictSchema ("Jack", 25)
--- "{\"minItems\":2,\"uniqueItems\":true,\"items\":[{\"maxLength\":4,\"pattern\":\"Jack\",\"minLength\":4,\"type\":\"string\",\"enum\":[\"Jack\"]},{\"maximum\":25,\"minimum\":25,\"multipleOf\":25,\"type\":\"number\",\"enum\":[25]}],\"maxItems\":2,\"type\":\"array\",\"enum\":[[\"Jack\",25]]}"
+-- "{\"enum\":[[\"Jack\",25]],\"items\":[{\"enum\":[\"Jack\"],\"maxLength\":4,\"minLength\":4,\"pattern\":\"Jack\",\"type\":\"string\"},{\"enum\":[25],\"maximum\":25,\"minimum\":25,\"multipleOf\":25,\"type\":\"number\"}],\"maxItems\":2,\"minItems\":2,\"type\":\"array\",\"uniqueItems\":true}"
 --
 -- >>> data Person = Person { name :: String, age :: Int } deriving (Generic)
 -- >>> instance ToJSON Person
 -- >>> encode $ sketchStrictSchema (Person "Jack" 25)
--- "{\"required\":[\"age\",\"name\"],\"properties\":{\"age\":{\"maximum\":25,\"minimum\":25,\"multipleOf\":25,\"type\":\"number\",\"enum\":[25]},\"name\":{\"maxLength\":4,\"pattern\":\"Jack\",\"minLength\":4,\"type\":\"string\",\"enum\":[\"Jack\"]}},\"maxProperties\":2,\"minProperties\":2,\"type\":\"object\",\"enum\":[{\"age\":25,\"name\":\"Jack\"}]}"
+-- "{\"required\":[\"name\",\"age\"],\"properties\":{\"name\":{\"enum\":[\"Jack\"],\"maxLength\":4,\"minLength\":4,\"pattern\":\"Jack\",\"type\":\"string\"},\"age\":{\"enum\":[25],\"maximum\":25,\"minimum\":25,\"multipleOf\":25,\"type\":\"number\"}},\"maxProperties\":2,\"minProperties\":2,\"enum\":[{\"age\":25,\"name\":\"Jack\"}],\"type\":\"object\"}"
 sketchStrictSchema :: ToJSON a => a -> Schema
 sketchStrictSchema = go . toJSON
   where
@@ -403,7 +397,7 @@
       where
         sz = length xs
         allUnique = sz == HashSet.size (HashSet.fromList (V.toList xs))
-    go js@(Object o) = mempty
+    go js@(Object o') = let o = KM.toHashMapText o' in mempty
       & type_         ?~ SwaggerObject
       & required      .~ names
       & properties    .~ fmap (Inline . go) (InsOrdHashMap.fromHashMap o)
@@ -411,19 +405,19 @@
       & minProperties ?~ fromIntegral (length names)
       & enum_         ?~ [js]
       where
-        names = HashMap.keys o
+        names = HashMap.keys (KM.toHashMapText o')
 
 class GToSchema (f :: * -> *) where
   gdeclareNamedSchema :: SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema
 
-instance OVERLAPPABLE_ ToSchema a => ToSchema [a] where
+instance {-# OVERLAPPABLE #-} ToSchema a => ToSchema [a] where
   declareNamedSchema _ = do
     ref <- declareSchemaRef (Proxy :: Proxy a)
     return $ unnamed $ mempty
       & type_ ?~ SwaggerArray
       & items ?~ SwaggerItemsObject ref
 
-instance OVERLAPPING_ ToSchema String where declareNamedSchema = plain . paramSchemaToSchema
+instance {-# OVERLAPPING #-} ToSchema String where declareNamedSchema = plain . paramSchemaToSchema
 instance ToSchema Bool    where declareNamedSchema = plain . paramSchemaToSchema
 instance ToSchema Integer where declareNamedSchema = plain . paramSchemaToSchema
 instance ToSchema Natural where declareNamedSchema = plain . paramSchemaToSchema
@@ -505,8 +499,6 @@
 
 instance ToSchema Version where declareNamedSchema = plain . paramSchemaToSchema
 
-#if __GLASGOW_HASKELL__ < 800
-#else
 type family ToSchemaByteStringError bs where
   ToSchemaByteStringError bs = TypeError
       ( Text "Impossible to have an instance " :<>: ShowType (ToSchema bs) :<>: Text "."
@@ -515,7 +507,6 @@
 
 instance ToSchemaByteStringError BS.ByteString  => ToSchema BS.ByteString  where declareNamedSchema = error "impossible"
 instance ToSchemaByteStringError BSL.ByteString => ToSchema BSL.ByteString where declareNamedSchema = error "impossible"
-#endif
 
 instance ToSchema IntSet where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Set Int))
 
@@ -523,7 +514,6 @@
 instance ToSchema a => ToSchema (IntMap a) where
   declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy [(Int, a)])
 
-#if MIN_VERSION_aeson(1,0,0)
 instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (Map k v) where
   declareNamedSchema _ = case toJSONKey :: ToJSONKeyFunction k of
       ToJSONKeyText  _ _ -> declareObjectMapSchema
@@ -538,25 +528,7 @@
 instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (HashMap k v) where
   declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Map k v))
 
-#else
-
-instance ToSchema a => ToSchema (Map String a) where
-  declareNamedSchema _ = do
-    schema <- declareSchemaRef (Proxy :: Proxy a)
-    return $ unnamed $ mempty
-      & type_ ?~ SwaggerObject
-      & additionalProperties ?~ schema
-
-instance ToSchema a => ToSchema (Map T.Text  a) where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Map String a))
-instance ToSchema a => ToSchema (Map TL.Text a) where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Map String a))
-
-instance ToSchema a => ToSchema (HashMap String  a) where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Map String a))
-instance ToSchema a => ToSchema (HashMap T.Text  a) where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Map String a))
-instance ToSchema a => ToSchema (HashMap TL.Text a) where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Map String a))
-
-#endif
-
-instance OVERLAPPING_ ToSchema Object where
+instance {-# OVERLAPPING #-} ToSchema Object where
   declareNamedSchema _ = pure $ NamedSchema (Just "Object") $ mempty
     & type_ ?~ SwaggerObject
     & description ?~ "Arbitrary JSON object."
@@ -643,9 +615,9 @@
     objectSchema keyToText = do
       valueRef <- declareSchemaRef (Proxy :: Proxy value)
       let allKeys   = [minBound..maxBound :: key]
-          mkPair k  =  (keyToText k, valueRef)
+          mkPair k  = (toText $ keyToText k, valueRef)
       return $ mempty
-        & type_ ?~ SwaggerObject
+        & type_      ?~ SwaggerObject
         & properties .~ InsOrdHashMap.fromList (map mkPair allKeys)
 
 -- | A 'Schema' for a mapping with 'Bounded' 'Enum' keys.
@@ -738,10 +710,10 @@
     where
       name = gdatatypeSchemaName opts (Proxy :: Proxy d)
 
-instance OVERLAPPABLE_ GToSchema f => GToSchema (C1 c f) where
+instance {-# OVERLAPPABLE #-} GToSchema f => GToSchema (C1 c f) where
   gdeclareNamedSchema opts _ = gdeclareNamedSchema opts (Proxy :: Proxy f)
 
-instance OVERLAPPING_ Constructor c => GToSchema (C1 c U1) where
+instance {-# OVERLAPPING #-} Constructor c => GToSchema (C1 c U1) where
   gdeclareNamedSchema = gdeclareNamedSumSchema
 
 -- | Single field constructor.
@@ -804,17 +776,17 @@
     fname = T.pack (fieldLabelModifier opts (selName (Proxy3 :: Proxy3 s f p)))
 
 -- | Optional record fields.
-instance OVERLAPPING_ (Selector s, ToSchema c) => GToSchema (S1 s (K1 i (Maybe c))) where
+instance {-# OVERLAPPING #-} (Selector s, ToSchema c) => GToSchema (S1 s (K1 i (Maybe c))) where
   gdeclareNamedSchema opts _ = fmap unnamed . withFieldSchema opts (Proxy2 :: Proxy2 s (K1 i (Maybe c))) False
 
 -- | Record fields.
-instance OVERLAPPABLE_ (Selector s, GToSchema f) => GToSchema (S1 s f) where
+instance {-# OVERLAPPABLE #-} (Selector s, GToSchema f) => GToSchema (S1 s f) where
   gdeclareNamedSchema opts _ = fmap unnamed . withFieldSchema opts (Proxy2 :: Proxy2 s f) True
 
-instance OVERLAPPING_ ToSchema c => GToSchema (K1 i (Maybe c)) where
+instance {-# OVERLAPPING #-} ToSchema c => GToSchema (K1 i (Maybe c)) where
   gdeclareNamedSchema _ _ _ = declareNamedSchema (Proxy :: Proxy c)
 
-instance OVERLAPPABLE_ ToSchema c => GToSchema (K1 i c) where
+instance {-# OVERLAPPABLE #-} ToSchema c => GToSchema (K1 i c) where
   gdeclareNamedSchema _ _ _ = declareNamedSchema (Proxy :: Proxy c)
 
 instance ( GSumToSchema f
@@ -859,7 +831,7 @@
   ref <- gdeclareSchemaRef opts proxy
   return $ gsumConToSchemaWith ref opts proxy schema
 
-instance OVERLAPPABLE_ (Constructor c, GToSchema f) => GSumToSchema (C1 c f) where
+instance {-# OVERLAPPABLE #-} (Constructor c, GToSchema f) => GSumToSchema (C1 c f) where
   gsumToSchema opts proxy schema = do
     tell (All False)
     lift $ gsumConToSchema opts proxy schema
diff --git a/src/Data/Swagger/Internal/Schema/Validation.hs b/src/Data/Swagger/Internal/Schema/Validation.hs
--- a/src/Data/Swagger/Internal/Schema/Validation.hs
+++ b/src/Data/Swagger/Internal/Schema/Validation.hs
@@ -50,6 +50,7 @@
 import           Data.Swagger.Internal
 import           Data.Swagger.Internal.Schema
 import           Data.Swagger.Lens
+import qualified Data.Aeson.KeyMap                   as KM
 
 -- | Validate @'ToJSON'@ instance matches @'ToSchema'@ for a given value.
 -- This can be used with QuickCheck to ensure those instances are coherent:
@@ -101,33 +102,33 @@
 -- <BLANKLINE>
 -- Swagger Schema:
 -- {
---     "required": [
---         "name",
---         "phone"
---     ],
---     "type": "object",
 --     "properties": {
---         "phone": {
---             "$ref": "#/definitions/Phone"
---         },
 --         "name": {
 --             "type": "string"
+--         },
+--         "phone": {
+--             "$ref": "#/definitions/Phone"
 --         }
---     }
+--     },
+--     "required": [
+--         "name",
+--         "phone"
+--     ],
+--     "type": "object"
 -- }
 -- <BLANKLINE>
 -- Swagger Description Context:
 -- {
 --     "Phone": {
---         "required": [
---             "value"
---         ],
---         "type": "object",
 --         "properties": {
 --             "value": {
 --                 "type": "string"
 --             }
---         }
+--         },
+--         "required": [
+--             "value"
+--         ],
+--         "type": "object"
 --     }
 -- }
 -- <BLANKLINE>
@@ -375,7 +376,7 @@
 validateObject o = withSchema $ \sch ->
   case sch ^. discriminator of
     Just pname -> case fromJSON <$> HashMap.lookup pname o of
-      Just (Success ref) -> validateWithSchemaRef ref (Object o)
+      Just (Success ref) -> validateWithSchemaRef ref (Object $ KM.fromHashMapText o)
       Just (Error msg)   -> invalid ("failed to parse discriminator property " ++ show pname ++ ": " ++ show msg)
       Nothing            -> invalid ("discriminator property " ++ show pname ++ "is missing")
     Nothing -> do
@@ -476,14 +477,14 @@
     (Just SwaggerNumber,  Number n)   -> sub_ paramSchema (validateNumber n)
     (Just SwaggerString,  String s)   -> sub_ paramSchema (validateString s)
     (Just SwaggerArray,   Array xs)   -> sub_ paramSchema (validateArray xs)
-    (Just SwaggerObject,  Object o)   -> validateObject o
+    (Just SwaggerObject,  Object o)   -> validateObject $ KM.toHashMapText o
     (Nothing, Null)                   -> valid
     (Nothing, Bool _)                 -> valid
     -- Number by default
     (Nothing, Number n)               -> sub_ paramSchema (validateNumber n)
     (Nothing, String s)               -> sub_ paramSchema (validateString s)
     (Nothing, Array xs)               -> sub_ paramSchema (validateArray xs)
-    (Nothing, Object o)               -> validateObject o
+    (Nothing, Object o)               -> validateObject $ KM.toHashMapText o
     bad -> invalid $ "expected JSON value of type " ++ showType bad
 
 validateParamSchemaType :: Value -> Validation (ParamSchema t) ()
diff --git a/src/Data/Swagger/Internal/TypeShape.hs b/src/Data/Swagger/Internal/TypeShape.hs
--- a/src/Data/Swagger/Internal/TypeShape.hs
+++ b/src/Data/Swagger/Internal/TypeShape.hs
@@ -1,7 +1,5 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE DataKinds #-}
-{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE UndecidableInstances #-}
@@ -37,11 +35,6 @@
 type family GenericHasSimpleShape t (f :: Symbol) (s :: TypeShape) :: Constraint where
   GenericHasSimpleShape t f Enumeration   = ()
   GenericHasSimpleShape t f SumOfProducts = ()
-#if __GLASGOW_HASKELL__ < 800
-  GenericHasSimpleShape t f Mixed = CannotDeriveSchemaForMixedSumType t
-
-class CannotDeriveSchemaForMixedSumType t where
-#else
   GenericHasSimpleShape t f Mixed =
     TypeError
       (     Text "Cannot derive Generic-based Swagger Schema for " :<>: ShowType t
@@ -51,7 +44,6 @@
       :$$:  Text "that matches aeson's Generic-based toJSON,"
       :$$:  Text "but that's not supported by some Swagger tools."
       )
-#endif
 
 -- | Infer a 'TypeShape' for a generic representation of a type.
 type family GenericShape (g :: * -> *) :: TypeShape
@@ -62,5 +54,3 @@
 type instance GenericShape (C1 c U1)        = Enumeration
 type instance GenericShape (C1 c (S1 s f))  = SumOfProducts
 type instance GenericShape (C1 c (f :*: g)) = SumOfProducts
-
-
diff --git a/src/Data/Swagger/Lens.hs b/src/Data/Swagger/Lens.hs
--- a/src/Data/Swagger/Lens.hs
+++ b/src/Data/Swagger/Lens.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FunctionalDependencies #-}
@@ -10,7 +9,6 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE UndecidableInstances #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
-#include "overlapping-compat.h"
 -- |
 -- Module:      Data.Swagger.Lens
 -- Maintainer:  Nickolay Kudasov <nickolay@getshoptv.com>
@@ -118,69 +116,63 @@
 -- OVERLAPPABLE instances
 
 instance
-#if __GLASGOW_HASKELL__ >= 710
-  OVERLAPPABLE_
-#endif
+  {-# OVERLAPPABLE #-}
   HasParamSchema s (ParamSchema t)
   => HasFormat s (Maybe Format) where
   format = paramSchema.format
 
 instance
-#if __GLASGOW_HASKELL__ >= 710
-  OVERLAPPABLE_
-#endif
+  {-# OVERLAPPABLE #-}
   HasParamSchema s (ParamSchema t)
   => HasItems s (Maybe (SwaggerItems t)) where
   items = paramSchema.items
 
 instance
-#if __GLASGOW_HASKELL__ >= 710
-  OVERLAPPABLE_
-#endif
+  {-# OVERLAPPABLE #-}
   HasParamSchema s (ParamSchema t)
   => HasMaximum s (Maybe Scientific) where
   maximum_ = paramSchema.maximum_
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasExclusiveMaximum s (Maybe Bool) where
   exclusiveMaximum = paramSchema.exclusiveMaximum
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasMinimum s (Maybe Scientific) where
   minimum_ = paramSchema.minimum_
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasExclusiveMinimum s (Maybe Bool) where
   exclusiveMinimum = paramSchema.exclusiveMinimum
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasMaxLength s (Maybe Integer) where
   maxLength = paramSchema.maxLength
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasMinLength s (Maybe Integer) where
   minLength = paramSchema.minLength
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasPattern s (Maybe Text) where
   pattern = paramSchema.pattern
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasMaxItems s (Maybe Integer) where
   maxItems = paramSchema.maxItems
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasMinItems s (Maybe Integer) where
   minItems = paramSchema.minItems
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasUniqueItems s (Maybe Bool) where
   uniqueItems = paramSchema.uniqueItems
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasEnum s (Maybe [Value]) where
   enum_ = paramSchema.enum_
 
-instance OVERLAPPABLE_ HasParamSchema s (ParamSchema t)
+instance {-# OVERLAPPABLE #-} HasParamSchema s (ParamSchema t)
   => HasMultipleOf s (Maybe Scientific) where
   multipleOf = paramSchema.multipleOf
diff --git a/src/Data/Swagger/Operation.hs b/src/Data/Swagger/Operation.hs
--- a/src/Data/Swagger/Operation.hs
+++ b/src/Data/Swagger/Operation.hs
@@ -80,9 +80,9 @@
 -- >>> let api = (mempty :: Swagger) & paths .~ [("/user", mempty & get ?~ ok & post ?~ ok)]
 -- >>> let sub = (mempty :: Swagger) & paths .~ [("/user", mempty & get ?~ mempty)]
 -- >>> encode api
--- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"},\"paths\":{\"/user\":{\"get\":{\"responses\":{\"200\":{\"description\":\"OK\"}}},\"post\":{\"responses\":{\"200\":{\"description\":\"OK\"}}}}}}"
+-- "{\"swagger\":\"2.0\",\"info\":{\"title\":\"\",\"version\":\"\"},\"paths\":{\"/user\":{\"get\":{\"responses\":{\"200\":{\"description\":\"OK\"}}},\"post\":{\"responses\":{\"200\":{\"description\":\"OK\"}}}}}}"
 -- >>> encode $ api & operationsOf sub . at 404 ?~ "Not found"
--- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"},\"paths\":{\"/user\":{\"get\":{\"responses\":{\"404\":{\"description\":\"Not found\"},\"200\":{\"description\":\"OK\"}}},\"post\":{\"responses\":{\"200\":{\"description\":\"OK\"}}}}}}"
+-- "{\"swagger\":\"2.0\",\"info\":{\"title\":\"\",\"version\":\"\"},\"paths\":{\"/user\":{\"get\":{\"responses\":{\"200\":{\"description\":\"OK\"},\"404\":{\"description\":\"Not found\"}}},\"post\":{\"responses\":{\"200\":{\"description\":\"OK\"}}}}}}"
 operationsOf :: Swagger -> Traversal' Swagger Operation
 operationsOf sub = paths.itraversed.withIndex.subops
   where
@@ -139,7 +139,7 @@
 -- >>> let api = (mempty :: Swagger) & paths .~ [("/user", mempty & get ?~ mempty)]
 -- >>> let res = declareResponse (Proxy :: Proxy Day)
 -- >>> encode $ api & setResponse 200 res
--- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"},\"paths\":{\"/user\":{\"get\":{\"responses\":{\"200\":{\"schema\":{\"$ref\":\"#/definitions/Day\"},\"description\":\"\"}}}}},\"definitions\":{\"Day\":{\"example\":\"2016-07-22\",\"format\":\"date\",\"type\":\"string\"}}}"
+-- "{\"swagger\":\"2.0\",\"info\":{\"title\":\"\",\"version\":\"\"},\"paths\":{\"/user\":{\"get\":{\"responses\":{\"200\":{\"description\":\"\",\"schema\":{\"$ref\":\"#/definitions/Day\"}}}}}},\"definitions\":{\"Day\":{\"example\":\"2016-07-22\",\"format\":\"date\",\"type\":\"string\"}}}"
 --
 -- See also @'setResponseWith'@.
 setResponse :: HttpStatusCode -> Declare (Definitions Schema) Response -> Swagger -> Swagger
diff --git a/src/Data/Swagger/Optics.hs b/src/Data/Swagger/Optics.hs
--- a/src/Data/Swagger/Optics.hs
+++ b/src/Data/Swagger/Optics.hs
@@ -29,7 +29,7 @@
 --         & at 200 ?~ ("OK" & #_Inline % #schema ?~ Ref (Reference "User"))
 --         & at 404 ?~ "User info not found")) ]
 -- :}
--- "{\"swagger\":\"2.0\",\"info\":{\"version\":\"\",\"title\":\"\"},\"paths\":{\"/user\":{\"get\":{\"produces\":[\"application/json\"],\"responses\":{\"404\":{\"description\":\"User info not found\"},\"200\":{\"schema\":{\"$ref\":\"#/definitions/User\"},\"description\":\"OK\"}}}}},\"definitions\":{\"User\":{\"type\":\"string\"}}}"
+-- "{\"swagger\":\"2.0\",\"info\":{\"title\":\"\",\"version\":\"\"},\"paths\":{\"/user\":{\"get\":{\"produces\":[\"application/json\"],\"responses\":{\"200\":{\"description\":\"OK\",\"schema\":{\"$ref\":\"#/definitions/User\"}},\"404\":{\"description\":\"User info not found\"}}}}},\"definitions\":{\"User\":{\"type\":\"string\"}}}"
 --
 -- For convenience optics are defined as /labels/. It means that field accessor
 -- names can be overloaded for different types. One such common field is
diff --git a/src/Data/Swagger/Schema/Generator.hs b/src/Data/Swagger/Schema/Generator.hs
--- a/src/Data/Swagger/Schema/Generator.hs
+++ b/src/Data/Swagger/Schema/Generator.hs
@@ -10,10 +10,10 @@
 import           Control.Lens.Operators
 import           Control.Monad                           (filterM)
 import           Data.Aeson
+import qualified Data.Aeson.KeyMap                       as KM
 import           Data.Aeson.Types
 import qualified Data.HashMap.Strict.InsOrd              as M
 import           Data.Maybe
-import           Data.Maybe
 import           Data.Proxy
 import           Data.Scientific
 import qualified Data.Set                                as S
@@ -94,7 +94,7 @@
               return . M.fromList $ zip additionalKeys (repeat . schemaGen defns $ dereference defns addlSchema)
             _                                      -> return []
           x <- sequence $ gens <> additionalGens
-          return . Object $ M.toHashMap x
+          return . Object . KM.fromHashMapText $ M.toHashMap x
   where
     dereference :: Definitions a -> Referenced a -> a
     dereference _ (Inline a)               = a
diff --git a/swagger2.cabal b/swagger2.cabal
--- a/swagger2.cabal
+++ b/swagger2.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >=1.10
 name:                swagger2
-version:             2.6
+version:             2.7
 
 synopsis:            Swagger 2.0 data model
 category:            Web, Swagger
@@ -22,14 +22,13 @@
     README.md
   , CHANGELOG.md
   , examples/*.hs
-  , include/overlapping-compat.h
 tested-with:
-  GHC ==8.0.2
-   || ==8.2.2
-   || ==8.4.4
+  GHC ==8.4.4
    || ==8.6.5
-   || ==8.8.1
-   || ==8.10.1
+   || ==8.8.4
+   || ==8.10.4
+   || ==8.10.7
+   || ==9.0.1
 
 custom-setup
   setup-depends:
@@ -37,7 +36,6 @@
 
 library
   hs-source-dirs:      src
-  include-dirs:        include
   exposed-modules:
     Data.Swagger
     Data.Swagger.Declare
@@ -61,38 +59,37 @@
 
   -- GHC boot libraries
   build-depends:
-      base             >=4.9      && <4.15
-    , bytestring       >=0.10.4.0 && <0.11
-    , containers       >=0.5.5.1  && <0.7
-    , template-haskell >=2.9.0.0  && <2.17
-    , time             >=1.4.2    && <1.10
-    , transformers     >=0.3.0.0  && <0.6
+      base             >=4.9       && <4.16
+    , bytestring       >=0.10.8.1  && <0.11
+    , containers       >=0.5.7.1   && <0.7
+    , template-haskell >=2.11.1.0  && <2.18
+    , time             >=1.6.0.1   && <1.10
+    , transformers     >=0.5.2.0   && <0.6
 
   build-depends:
-      mtl              >=2.1     && <2.3
+      mtl              >=2.2.2   && <2.3
     , text             >=1.2.3.0 && <1.3
 
   -- other dependencies
   build-depends:
-      base-compat-batteries     >=0.10.4   && <0.12
-    , aeson                     >=1.4.2.0  && <1.5
+      base-compat-batteries     >=0.11.1   && <0.12
+    , aeson                     >=2.0.0.0  && <2.1
     , aeson-pretty              >=0.8.7    && <0.9
     -- cookie 0.4.3 is needed by GHC 7.8 due to time>=1.4 constraint
     , cookie                    >=0.4.3    && <0.5
-    , generics-sop              >=0.3.2.0  && <0.6
+    , generics-sop              >=0.5.1.0  && <0.6
     , hashable                  >=1.2.7.0  && <1.4
-    , http-media                >=0.7.1.2  && <0.9
+    , http-media                >=0.8.0.0  && <0.9
     , insert-ordered-containers >=0.2.3    && <0.3
-    , lens                      >=4.16.1   && <4.20
+    , lens                      >=4.16.1   && <5.1
     , network                   >=2.6.3.5  && <3.2
-    , optics-core               >=0.2      && <0.4
-    , optics-th                 >=0.2      && <0.4
+    , optics-core               >=0.2      && <0.5
+    , optics-th                 >=0.2      && <0.5
     , scientific                >=0.3.6.2  && <0.4
-    , transformers-compat       >=0.3      && <0.7
     , unordered-containers      >=0.2.9.0  && <0.3
     , uuid-types                >=1.0.3    && <1.1
     , vector                    >=0.12.0.1 && <0.13
-    , QuickCheck                >=2.10.1   && <2.14
+    , QuickCheck                >=2.10.1   && <2.15
 
   default-language:    Haskell2010
 
@@ -123,14 +120,14 @@
 
   -- test-suite only dependencies
   build-depends:
-      hspec                >=2.5.5   && <2.8
+      hspec                >=2.5.5   && <2.9
     , HUnit                >=1.6.0.0 && <1.7
     , quickcheck-instances >=0.3.19  && <0.14
     , utf8-string          >=1.0.1.1 && <1.1
 
   -- https://github.com/haskell/cabal/issues/3708
   build-tool-depends:
-    hspec-discover:hspec-discover >=2.5.5 && <2.8
+    hspec-discover:hspec-discover >=2.5.5 && <2.9
 
   other-modules:
     SpecCommon
diff --git a/test/Data/Swagger/CommonTestTypes.hs b/test/Data/Swagger/CommonTestTypes.hs
--- a/test/Data/Swagger/CommonTestTypes.hs
+++ b/test/Data/Swagger/CommonTestTypes.hs
@@ -15,6 +15,7 @@
 import           Data.Proxy
 import           Data.Set              (Set)
 import qualified Data.Text             as Text
+import           Data.Word
 import           GHC.Generics
 
 import           Data.Swagger
@@ -675,5 +676,31 @@
 {
   "type": "string",
   "format": "hh:MM:ss"
+}
+|]
+
+
+-- ========================================================================
+-- UnsignedInts
+-- ========================================================================
+data UnsignedInts = UnsignedInts
+  { unsignedIntsUint32 :: Word32
+  , unsignedIntsUint64 :: Word64
+  } deriving (Generic)
+
+instance ToSchema UnsignedInts where
+  declareNamedSchema = genericDeclareNamedSchema defaultSchemaOptions
+    { fieldLabelModifier = map toLower . drop (length "unsignedInts") }
+
+unsignedIntsSchemaJSON :: Value
+unsignedIntsSchemaJSON = [aesonQQ|
+{
+  "type": "object",
+  "properties":
+    {
+      "uint32": { "type": "integer", "format": "int32", "minimum": 0, "maximum": 4294967295 },
+      "uint64": { "type": "integer", "format": "int64", "minimum": 0, "maximum": 18446744073709551615 }
+    },
+  "required": ["uint32", "uint64"]
 }
 |]
diff --git a/test/Data/Swagger/Schema/ValidationSpec.hs b/test/Data/Swagger/Schema/ValidationSpec.hs
--- a/test/Data/Swagger/Schema/ValidationSpec.hs
+++ b/test/Data/Swagger/Schema/ValidationSpec.hs
@@ -1,8 +1,8 @@
-{-# LANGUAGE CPP                 #-}
 {-# LANGUAGE DeriveGeneric       #-}
 {-# LANGUAGE PackageImports      #-}
 {-# LANGUAGE RecordWildCards     #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleInstances   #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Data.Swagger.Schema.ValidationSpec where
 
@@ -10,6 +10,8 @@
 import           Control.Lens                        ((&), (.~), (?~))
 import           Data.Aeson
 import           Data.Aeson.Types
+import           Data.Aeson.Key
+import qualified Data.Aeson.KeyMap                   as KM
 import           Data.Hashable                       (Hashable)
 import           Data.HashMap.Strict                 (HashMap)
 import qualified Data.HashMap.Strict                 as HashMap
@@ -123,9 +125,9 @@
 
 invalidPersonToJSON :: Person -> Value
 invalidPersonToJSON Person{..} = object
-  [ T.pack "personName"  .= toJSON name
-  , T.pack "personPhone" .= toJSON phone
-  , T.pack "personEmail" .= toJSON email
+  [ fromString "personName"  .= toJSON name
+  , fromString "personPhone" .= toJSON phone
+  , fromString "personEmail" .= toJSON email
   ]
 
 -- ========================================================================
@@ -252,7 +254,7 @@
     & additionalProperties ?~ AdditionalPropertiesAllowed True
 
 instance Arbitrary FreeForm where
-  arbitrary = (FreeForm . fromList) <$> genObj
+  arbitrary = FreeForm . fromList <$> genObj
     where
       genObj = listOf $ do
         k <- arbitrary
@@ -270,9 +272,12 @@
   -- Weights are almost random
   -- Uniform oneof tends not to build complex objects cause of recursive call.
   arbitrary = resize 4 $ frequency
-    [ (3, Object <$> arbitrary)
+    [ (3, Object . KM.fromHashMapText <$> arbitrary)
     , (3, Array  <$> arbitrary)
     , (3, String <$> arbitrary)
     , (3, Number <$> arbitrary)
     , (3, Bool   <$> arbitrary)
     , (1, return Null) ]
+
+instance Arbitrary (KM.KeyMap Value) where
+  arbitrary = KM.fromHashMapText <$> arbitrary
diff --git a/test/Data/Swagger/SchemaSpec.hs b/test/Data/Swagger/SchemaSpec.hs
--- a/test/Data/Swagger/SchemaSpec.hs
+++ b/test/Data/Swagger/SchemaSpec.hs
@@ -85,6 +85,7 @@
       context "Status (sum of unary constructors)" $ checkToSchema (Proxy :: Proxy Status) statusSchemaJSON
       context "Character (ref and record sum)" $ checkToSchema (Proxy :: Proxy Character) characterSchemaJSON
       context "Light (sum with unwrapUnaryRecords)" $ checkToSchema (Proxy :: Proxy Light) lightSchemaJSON
+    context "UnsignedInts" $ checkToSchema (Proxy :: Proxy UnsignedInts) unsignedIntsSchemaJSON
     context "Schema name" $ do
       context "String" $ checkSchemaName Nothing (Proxy :: Proxy String)
       context "(Int, Float)" $ checkSchemaName Nothing (Proxy :: Proxy (Int, Float))
diff --git a/test/Data/SwaggerSpec.hs b/test/Data/SwaggerSpec.hs
--- a/test/Data/SwaggerSpec.hs
+++ b/test/Data/SwaggerSpec.hs
@@ -46,6 +46,7 @@
   describe "OAuth2 Security Definitions with merged Scope" $ oAuth2SecurityDefinitionsExample <=> oAuth2SecurityDefinitionsExampleJSON
   describe "Composition Schema Example" $ compositionSchemaExample <=> compositionSchemaExampleJSON
   describe "Swagger Object" $ do
+    context "Example with no paths" $ emptyPathsFieldExample <=> emptyPathsFieldExampleJSON
     context "Todo Example" $ swaggerExample <=> swaggerExampleJSON
     context "PetStore Example" $
       it "decodes successfully" $ do
@@ -536,6 +537,18 @@
 -- =======================================================================
 -- Swagger object
 -- =======================================================================
+
+emptyPathsFieldExample :: Swagger
+emptyPathsFieldExample = mempty
+
+emptyPathsFieldExampleJSON :: Value
+emptyPathsFieldExampleJSON = [aesonQQ|
+{
+  "swagger": "2.0",
+  "info": {"version": "", "title": ""},
+  "paths": {}
+}
+|]
 
 swaggerExample :: Swagger
 swaggerExample = mempty
diff --git a/test/SpecCommon.hs b/test/SpecCommon.hs
--- a/test/SpecCommon.hs
+++ b/test/SpecCommon.hs
@@ -1,18 +1,20 @@
 module SpecCommon where
 
 import Data.Aeson
+import Data.Aeson.Key
 import Data.ByteString.Builder (toLazyByteString)
-import qualified Data.Foldable as F
+import qualified Data.Foldable       as F
 import qualified Data.HashMap.Strict as HashMap
-import qualified Data.Vector as Vector
+import qualified Data.Aeson.KeyMap   as KM
+import qualified Data.Vector         as Vector
 
 import Test.Hspec
 
 isSubJSON :: Value -> Value -> Bool
 isSubJSON Null _ = True
-isSubJSON (Object x) (Object y) = HashMap.keys x == HashMap.keys i && F.and i
+isSubJSON (Object x) (Object y) = map toText (KM.keys x) == HashMap.keys i && F.and i
   where
-    i = HashMap.intersectionWith isSubJSON x y
+    i = HashMap.intersectionWith isSubJSON (KM.toHashMapText x) (KM.toHashMapText y)
 isSubJSON (Array xs) (Array ys) = Vector.length xs == Vector.length ys && F.and (Vector.zipWith isSubJSON xs ys)
 isSubJSON x y = x == y
 
